[JVM] 클래스 변수는 초기화를 안 해도 되지만 인스턴스 변수는 초기화해야만 하는 이유
클래스 변수와 인스턴스 변수의 일반적인 차이
클래스 변수와 인스턴스 변수의 차이점이라면 많은 블로그들에서 설명해주고 있습니다.
대표적으로 아래와 같죠.
클래스 변수와 인스턴스 변수의 초기화 차이
그렇다면 초기화하지않고 선언만 해주었을때 아래의 코드의 결과는 무엇이 나올까요?
public class VariableTest {
static int a;
public static void main(String[] args) {
System.out.println(a);
}
}
결과는 0이 나옵니다. 만약 String 객체로 바꾼다면 null이 나오게 됩니다.
그렇다면 인스턴스 변수로 바꾸면 어떻게 나올까요?
네 초기화가 되어있지 않아서 컴파일에서 에러가 나옵니다.
그렇다면 클래스 변수는 초기화를 하지 않아도 자동으로 할당이 되는데, 인스턴스 변수는 자동으로 초기화를 시켜주지 않는 이유가 무엇일까요?
이는 클래스가 초기화 되는 방식의 차이입니다.
클래스 변수와 달리 지역 변수는 '준비'단계가 없습니다. 사실 클래스 변수는 초깃값이 두 번 할당됩니다.
1. 준비 단계에서는 시스템 초깃값이 자동으로 할당되며
2. 초기화 단계에서는 개발자가 정의한 초깃값이 할당된다.
따라서 자바 코드로 초기화를 안시켜도 클래스 변수에는 명확한 초깃값이 할당되어 있기에 특이사항이 없습니다. 하지만 지역 변수는 '준비' 단계가 없기때문에 시스템 초깃값이 자동으로 할당되어있지 않아 컴파일에서 걸러내는 것입니다.
마지막으로 정리하자면 클래스 로드는 5 단계로 나뉩니다.
로딩 -> 검증 -> 준비 -> 해석 ->초기화
여기서 준비는 클래스 변수를 메모리에 할당하고 초깃값을 설정하는 단계입니다.
1. 인스턴스 변수가 아닌 클래스 변수만 할되며, 인스턴스 변수는 객체가 인스턴스화될때 객체와 함께 자바 힙에 할당된다.
2. 클래스 변수에 할당하는 초깃값은 해당 데이터 타입의 제로값이다.
따라서 데이터 저장 공간이 다르기에 처리하는 방식도 다른 이유에서 발생한 경우였습니다.