hovi·2023년 5월 30일
0

JAVA

목록 보기
10/36

데이터 타입 분류

기본 타입과 참조 타입으로 선언된 변수의 차이점은 저장되는 값이 다르다는 점 입니다.

기본 타입은 선언된 변수에 실제 값이 저장되지만 참조 타입은 변수에 실제값이 저장된 주소를 가지고 있습니다.

변수와 메모리 구조

메소드 영역

메소드 영역에는 코드에서 사용되는 클래스들을 클래스 로도로 읽어 클래스 별로 런타임 상수 풀, 필드 / 메소드 데이터, 메소드 코드, 생성자 코드 등을 분류해서 저장합니다. 메소드 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역입니다.

힙 영역

힙 영역은 객체와 배열이 생성되는 영역입니다. 힙 영역에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다. 참조하는 변수나 필드가 없다면 의미 없는 객체가 되기 때문에 이것을 쓰레기로 취급하고 JVM은 Garbage Collector를 실행시켜 스레기 객체를 힙 영역에서 자동으로 제거합니다.

그렇기 때문에 개발자는 객체를 제거하기 위해 별도의 코드를 작성할 필요가 없습니다.

Garbage Collector의 존재가 C언어와의 차이점 중 하나입니다. C언어에서 참조 변수(포인터)를 사용하게되면 직접 쓰레기를 제거해줘야 하기 때문입니다.

스택 영역

JVM 스택 영역은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당됩니다. 자바 프로그램에서 추가적으로 스레드를 생성하지 않는다면 main 스레드만 존재하므로 JVM 스택도 하나입니다. JVM 스택은 메소드를 호출할 때마다 프레임을 추가하고 메소드가 종료되면 해당 프레임을 제거하는 동작을 수행합니다.

프레임 내부에는 로컬 변수 스택이 있는데 기본 타입 변수와 참조 타입 변수가 추가되거나 제거됩니다. 변수는 선언된 블록 안에서만 스택으로 존재하고 블록을 벗어나면 스택에서 제거됩니다. 이는 메소드, if문, for문 등에서 내부에서 생성된 변수는 해당 로컬 변수 스택에만 존재하여 해당 구문을 빠져 나오게되면 제거가 되여 외부에서는 사용이 불가능 하다는 것을 말합니다. 배열 같은 경우에는 배열의 변수는 스택 영역에 생성되지만 배열의 데이터 자체는 Heap 영역에 생성되어 제거되지 않습니다. 즉 Java에서 배열은 객체로 취급을 합니다.

참조 타입과 참조 변수

자바의 타입은 기본 타입과 참조 타입으로 분류 됩니다.

기본 타입은 정수, 실수, 문자, 논리값 등을 저장하는 타입을 말 합니다.

참조 타입은 객체의 번지를 참조하는 타입으로 배열, 열거 클래스, 인터페이스, 문자열을 말 합니다.

기본 타입은 값을 저장하고 참조 타입은 주소를 저장 합니다. (자바에서의 객체 주소는 해시 코드로 사용)

기본 타입 변수

int age = 25;
double price = 100.5;

참조 타입 변수

String name = "Americano";
String group = "Coffee";

메모리 사용 영역

참조 타입 변수는 스택 영역에 힙 영역의 객체 주소를 가집니다.

(C언어의 동적 할당과 유사 합니다.)

null과 NullPointerException

참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 뜻으로 null값을 가질 수 있습니다. (즉, 참조형 타입의 기본값으로 사용할 수 있습니다.)

null값도 초기값으로 사용 할 수 있기 때문에 null로 초기화된 참조 변수는 스택 영역에 생성 됩니다.

int[] intArray = null;
String str = (String) null;
Interger val = (Interger) null;
  • 참조 타입의 변수가 참조하는 값이 없는 경우, 이를 언박싱 하게 되면, NullPointerException 이 발생 합니다.
Integer boxedValue = null;
  int intValue = boxedValue; // NullPointerException 발생
  System.out.println(intValue);

참조변수의 ==, != 연산

기본 타입 변수의 ==, != 연산은 변수의 값이 같은지 아닌지를 조사 하지만 참조 타입 변수들 간의 ==, != 연산은 동일한 객체를 참조하는지 확인할 때 사용 합니다.

public class Main {
    public static void main(String[] args) {
        String strVal1 = "나희도";
        String strVal2 = "나희도";
        String strVal3 = new String("나희도");

        if(strVal1 == strVal3) {
            System.out.println("strVal1과 strVal2는 참조가 같음");
        } else {
            System.out.println("strVal1과 strVal2는 참조가 다름");
        }

        if(strVal1.equals(strVal3)) {
            System.out.println("strVal1과 strVal2는 참조가 같음");
        }
    }
}
profile
풀스택 예비 개발자

0개의 댓글