자바의 정적 초기화 블록은 중괄호로 묶인 코드 블록으로, static 키워드로 시작합니다. 이 블록은 클래스를 JVM에 로드할 때 한 번만 실행되며, 해당 클래스의 인스턴스가 생성되기 전과 모든 정적 메서드가 호출되기 전입니다. 그의 주요 작업은 정적 변수를 복잡하게 초기화하는 것입니다.
public class Example { static int staticValue; static { staticValue = 10; // 복잡한 초기화 로직 System.out.println("정적 초기화 블록이 실행되었습니다"); } }
정적 초기화 블록은 특히 정적 변수가 다른 자원에 의존하거나 클래스 로드 시 처리가 필요한 경우에 유용합니다.
질문: "정적 블록과 자바에서 정적 변수의 초기화가 클래스 내에서 선언된 순서가 다를 때 어떤 순서로 실행됩니까?"
정답: 모든 정적 변수와 블록은 클래스 소스 코드에서 선언된 순서(위에서 아래로)로 초기화됩니다. 정적 블록에 있는 정적 변수가 그 정의 위에 위치할 경우, 컴파일 오류를 일으키거나 예상치 못한 값을 초래할 수 있습니다.
class Order { static { System.out.println(X); // 기본값: 0 } static int X = 100; static { System.out.println(X); // 100 } }
이야기
큰 프로젝트에서 정적 블록을 통해 로거를 초기화했으나, 변수 선언과 정적 블록을 쪼개면서 로거 변수가 호출 시점에 초기화되지 않아, 클래스 로드 중 로깅 시 NullPointerException이 발생했습니다.
이야기
JDBC 유틸리티를 개발하면서 드라이버 초기화가 정적 블록에서 이루어졌습니다. 한 개발자가 경로를 포함하는 String 변수를 정적 블록 아래로 이동시켰고, 코드가 DB에 올바르게 연결되지 않게 되어 경로가 null이 되었습니다.
이야기
분산 시스템에서 구성 데이터 로드에 문제가 발생했습니다: 일부 로직이 서로 참조하는 여러 클래스의 정적 블록을 통해 구현되어, 잘못된 정적 블록 및 의존성 조직으로 인해 순환 초기화와 StackOverflowError가 애플리케이션 시작 시 발생했습니다.