코린이의 소소한 공부노트

변수의 초기화 본문

Java

변수의 초기화

무지맘 2022. 3. 12. 22:37

변수는 선언 위치/방법에 따라 클래스 변수(class variable, cv), 인스턴스 변수(instance variable, iv), 지역 변수(local variable, lv)로 나뉜다. 변수의 종류만큼 변수 초기화 방법도 다양하다.

 

[지역 변수 초기화] 수동 초기화: 변수 선언 후 대입 연산자를 이용해 직접 값을 넣어주는 것

class Test{
    // iv
    int x;
    int y = x;

    // im
    void method1(){
        // lv
        int i;
        int j = i; // error: The local variable i may not have been initialized
    }
}

메서드 호출 스택은 무한 제공되는 것이 아니라 한정적으로 할당된 메모리에 메서드가 쌓였다 지워졌다 한다. 그리고 빠른 작업을 위해 메서드가 스택에서 제거되면 메모리 내용을 지우는 것이 아니라, 메서드가 추가될 때마다 새 값을 덮어쓴다. 상황이 이렇다 보니 메모리에 무엇이 남아있는지 알 수없다. 때문에 lv는 수동 초기화를 하고 써야 하는데, i를 초기화하지 않은 상태로 j에 그 값을 대입하려 하기 때문에 에러가 발생한 것이다.

 

[멤버 변수 초기화] 자동 초기화 / 간단 초기화 / 복잡 초기화

1. 자동 초기화: 변수 생성 시 해당 타입의 기본값으로 알아서 초기화

boolean char byte short int long float double 참조형
false '\u0000' 0 0 0 0L 0.0f 0.0 null

  - cv 초기화: 프로그램이 실행돼 파일이 로딩됐을 때(1번)

  - iv 초기화: 인스턴스가 생성될 때(매번)

2. 간단 초기화: 대입 연산자 =를 이용한 명시적 초기화

class car{
    // iv
    int door = 4; // 기본형 변수 초기화
    Engine e = new Engine(); // 참조형 변수 초기화
}

참조형 변수의 경우 new 키워드를 사용하지 않으면 기본적으로 null로 초기화가 된다. 즉 참조변수가 가리키는 객체가 없다는 뜻이기 때문에 별 의미가 없다. 때문에 참조형 변수의 의미 있는 초기화는 new 키워드를 이용해 객체를 생성한 것까지를 말한다.

3. 복잡 초기화 - 초기화 블록, 생성자

1) 초기화 블록 { }: 초기화 작업이 복잡할 경우 블록 안에 여러 문장을 넣어 초기화

  - 인스턴스 초기화 블록: { } - iv 초기화, 많이 사용하지 않음

  - 클래스 초기화 블록: static { } - cv 초기화

// cv
static int[] arr = new int[10]; // 명시적 초기화. 배열 생성
// arr의 모든 요소는 int의 기본값인 0으로 자동 초기화
// 나는 1부터 10까지 중 랜덤으로 초기화가 되는 것을 원한다!

static { // 클래스 초기화 블럭 - 배열 arr을 난수로 채우기
  for( int i=0 ; i<arr.length ; i++)
    arr[i] = (int)(Math.random()*10)+1;
}

2) 생성자: iv 초기화

  - 2022.03.12 - [Java] - 생성자

  - 2022.03.12 - [Java] - 생성자 this() vs 참조변수 this

 

간단하게 정리해보자면

1) lv 초기화: 수동 초기화

2) cv 초기화: 자동(기본값) / 간단(=) / 복잡(static {}) 초기화

3) iv 초기화: 자동(기본값) / 간단(=) / 복잡(생성자) 초기화

 

cv와 iv 초기화 예시 코드를 보면서 머릿속에 정리가 잘 됐는지 확인해보자. 초기화는 cv -> iv, 자동 -> 간단 -> 복잡 초기화 순으로 진행된다.

class Test{
    // 간단 초기화 = 명시적 초기화
    static int cv = 1;
    int iv = 1;

    // 복잡 초기화
    static{ cv = 2; } // 클래스 초기화 블럭
    { iv = 2; } // 인스턴스 초기화 블럭
    Test() { iv = 3; } // 생성자
}
// 이후 메인 메서드에서..
Test t = new Test();
프로그램이 실행됨   객체 생성  
순서 1 2 3 4 5 6 7
방법 자동 간단 { } 자동 간단 { } 생성자
cv 0 1 2 2 2 2 2
iv   0 1 2 3

 

'Java' 카테고리의 다른 글

메서드 오버라이딩 (+오버로딩과의 차이점)  (0) 2022.03.22
클래스 간의 관계 - 상속, 포함  (0) 2022.03.15
생성자 this() vs 참조변수 this  (0) 2022.03.12
생성자  (0) 2022.03.12
메서드 오버로딩  (0) 2022.03.09