본문으로 건너뛰기
개발 머꼬
개발 노트Java
hohyeon.dev16

static 필드 초기화 순서 때문에 NullPointerException이 난 이유

  • #Common Pitfall
  • #Engineering Note
  • #Java

문제 발생

같은 클래스 안의 두 static 필드 중 하나가 다른 하나를 참조하도록 만들었는데, 애플리케이션 시작 시점에 NullPointerException이 발생했습니다.

public class Config {
    static String greeting = buildGreeting(); // BASE_NAME을 참조
    static String BASE_NAME = "MEOKKO";       // 아직 초기화 안 됨

    static String buildGreeting() {
        return "Hello, " + BASE_NAME; // 이 시점에 BASE_NAME은 null
    }
}

원인 분석

Java의 static 필드/블록은 클래스에 선언된 순서대로, 클래스가 처음 로드될 때 위에서 아래로 실행됩니다. greetingBASE_NAME보다 먼저 선언되어 있으므로, greeting을 초기화하는 시점에는 BASE_NAME이 아직 실행되지 않은 상태 — 즉 기본값인 null(참조 타입의 기본값)입니다.

이 문제는 두 필드가 같은 클래스 안에 있을 때만 발생합니다. 서로 다른 클래스 간의 static 초기화 순서는 "어느 클래스가 먼저 실제로 사용(로드)되는가"에 따라 결정되므로 더 예측하기 어렵고, 순환 참조가 있다면 한쪽이 완전히 초기화되지 않은 상태로 관찰될 수도 있습니다.

해결 방안

  1. 같은 클래스 안에서는 static 필드 선언 순서를 의존 관계에 맞게 배치합니다 — 다른 필드를 참조하는 필드는 참조 대상보다 아래에 선언합니다.
public class Config {
    static String BASE_NAME = "MEOKKO"; // 먼저 선언
    static String greeting = buildGreeting(); // 이제 정상 참조

    static String buildGreeting() {
        return "Hello, " + BASE_NAME;
    }
}
  1. 순서에 의존하는 것 자체가 위험 신호일 수 있습니다 — 값이 필요한 시점에 지연 계산(lazy)하도록 메서드로 바꾸는 것도 방법입니다.
static String getGreeting() {
    return "Hello, " + BASE_NAME; // 호출 시점에 평가되므로 순서 문제 없음
}
  1. 클래스 간 static 초기화 순서 문제(순환 의존 등)가 의심된다면, static 상태 자체를 줄이고 명시적인 초기화 메서드(애플리케이션 시작 시 순서를 직접 제어)로 옮기는 것을 검토합니다.
  2. IDE나 정적 분석 도구가 "forward reference" 관련 경고를 준다면 무시하지 말고 확인합니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.