0%

자바 명시적 초기화, 초기화 블럭 고찰

의문 발생

자바 기본서를 보는 도중 책의 내용을 제가 헷갈릴 뻔해서 정리하고자 합니다. 일반적인 상황에서는 발생하는 일이 아니지만 신기한 점이 있었습니다.

책의 내용

맴버 변수의 초기화에는 3가지 방법이 있습니다.

  1. 명시적 초기화
  2. 생성자
  3. 초기화 블럭

명시적 초기화

변수를 선언과 동시에 초기화하는 것을 명시적 초기화라고 합니다.

1
2
3
class Car {
int speed = 100;
}

초기화 블럭

초기화 블럭에는 클래스 초기화 블럭인스턴스 초기화 블럭이 있습니다. 인스턴스 초기화 블럭을 만드는 방법은 클래스 내부에 {}를 사용하면 됩니다. 클래스 초기화 블럭은 인스턴스 초기화 블럭 앞에 static을 붙이면 됩니다.

1
2
3
4
5
6
7
8
Car() {
static int count = 0;
int serialNo;
{
count++;
serialNo = count;
}
}

이렇게 사용을 하면 여러 생성자의 중복 코드를 줄일 수 있습니다.

초기화 순서

초기화 시점

  • 클래스 변수 초기화 시점: 클래스가 처음 로딩될 때
  • 인스턴스 변수 초기화 시점: 인스턴스가 생성될 때

초기화 순서

  • 클래스 변수 초기화 순서: 기본값 -> 명시적 초기화 -> 클래스 초기화 블럭
  • 인스턴스 변수 초기화 순서: 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자

나의 이해

코드 순서상 초기화 블럭이 먼저 오더라도 명시적 초기화가 항상 먼저 실행된다고 생각했습니다. 물론 틀린생각이지만 이해를 하기 위해 코드를 작성해 보았습니다.

실험

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Main {
public static void main(String[] args) {
B b = new B();
b.print();
}
}

class B{
String a = "인스턴스 명시적 초기화";
{
a = "인스턴스 초기화 블럭";
}

static {
b = "클래스 초기화 블럭";
}
static String b = "클래스 명시적 초기화";

public void print(){
System.out.println(a);
System.out.println(b);
}
}

실행결과

실행결과

항상 명시적 초기화가 먼저될거라는 예상과 달리 코드 작성 순서에 따라서 초기화 순서가 달라짐을 알 수 있었습니다.

특이한 점을 보면 클래스 초기화 블럭에 있는 b는 변수가 선언이 되지 않고 사용해도 오류가 나지 않는다는 점 입니다.

위 코드에서 b 변수 선언 -> 클래스 초기화 블럭 -> 클래스 명시적 초기화 순으로 실행된다는 것을 알 수 있습니다.

결론

  • 생성자는 제일 마지막에 실행됩니다.
  • 당연하게도 명시적 초기화초기화 블럭은 코드 작성 순서에 따라 실행 순서가 달라집니다.
  • 그러나 가독성을 위해서 명시적 초기화 -> 초기화 코드 블럭 -> 생성자 순으로 작성하는 것이 좋습니다.
  • 엄밀히 말하면 명시적 초기화변수 선언동시초기화가 되지는 않습니다.