자바의 이니셜라이저 블록(Initializer Block)은 클래스 안에 중괄호({ })로 감싸 선언하는 특별한 코드 블록입니다. 여러 생성자에서 반복해서 수행해야 하는 공통 초기화 작업을 한 곳에 모아두면 코드 중복을 줄이고 유지보수성을 크게 높일 수 있습니다. 아래 예제를 통해 동작 방식을 살펴보겠습니다.
예제 코드
import java.io.*;
public class Demo{
{
System.out.println("The common constructor has been invoked");
}
public Demo(){
System.out.println("The default constructor has been invoked");
}
public Demo(int x){
System.out.println("The parametrized constructor has been invoked");
}
public static void main(String arr[]){
Demo my_obj_1, my_obj_2;
System.out.println("The Demo objects have been created.");
my_obj_1 = new Demo();
my_obj_2 = new Demo(89);
}
}
실행 결과
The Demo objects have been created. The common constructor has been invoked The default constructor has been invoked The common constructor has been invoked The parametrized constructor has been invoked
코드 분석
Demo 클래스는 매개변수가 없는 기본 생성자, int 타입 매개변수를 받는 생성자, 그리고 프로그램의 진입점인 main 메서드로 구성되어 있습니다. main 메서드 안에서는 Demo 객체 두 개를 생성하는데, 하나는 인자 없이, 다른 하나는 정수 89를 전달하여 만듭니다.
실행 순서 상세 분석
- 프로그램이 시작되면 먼저 "The Demo objects have been created." 문장이 출력됩니다. 이 시점에는 아직 객체가 만들어지지 않았으므로 이니셜라이저 블록은 실행되지 않습니다.
new Demo()가 호출되면 이니셜라이저 블록이 먼저 실행되어 "The common constructor has been invoked"가 출력된 뒤, 기본 생성자의 본문이 이어서 실행됩니다.new Demo(89)가 호출되어도 마찬가지로 이니셜라이저 블록이 먼저 실행되고, 그다음 매개변수 생성자의 본문이 실행됩니다.
핵심은 어떤 생성자를 사용하든 이니셜라이저 블록이 항상 생성자 본문보다 먼저 실행된다는 점입니다. 실제로 컴파일러는 이 블록의 코드를 모든 생성자 안으로 복사하며, 부모 클래스 생성자 호출(super()) 바로 다음 위치에 배치합니다.
인스턴스 블록과 static 블록의 차이
- 인스턴스 이니셜라이저 블록: 객체가 생성될 때마다 매번 실행됩니다. 위 예제에서는 생성자가 두 번 호출되었으므로 블록도 두 번 실행되었습니다.
- static 이니셜라이저 블록(static { }): 클래스가 메모리에 처음 로딩될 때 단 한 번만 실행됩니다. JDBC 드라이버 로딩이나 정적 설정값 초기화 등에 주로 활용됩니다.
활용 시 주의 사항
- 블록은 소스 코드에 선언된 순서대로 실행되므로, 필드 초기화와 함께 사용할 때는 선언 순서를 고려해야 합니다.
- 블록 안에서는
this(...)호출이나return문을 사용할 수 없습니다. - 공통 초기화 로직이 단순하다면 private 헬퍼 메서드나 생성자 체이닝(
this()호출)으로 대체하는 편이 더 명확하고 읽기 쉬울 수 있습니다.
마무리
이니셜라이저 블록은 여러 생성자가 공유하는 초기화 코드를 깔끔하게 통합할 수 있는 자바의 유용한 문법입니다. 다만 무분별하게 사용하기보다는, 실제로 여러 생성자에 걸친 공통 로직이 존재할 때 선택적으로 활용하는 것이 좋습니다.