Java - Enum 순환참조 Error

Tae Yun Choi·2023년 3월 29일
0

개발새발 Java

목록 보기
2/4
post-thumbnail

문제

  • Java에서 간단한 콘솔 프로그램을 만드는데 오류가 발생했다.
  • ExceptionInInitializerError, NullPointerException
  • 자바에 무지한 상태로 로그들을 찍으며 무작정 찾아보기 시작했다.

해결

  • 원인은 바로 순환참조, 정확히는 그냥 메모리에 없는 값을 참조하려해서 발생하였다.
public enum Menu {
    KIMBOB(new MenuNumber("1"), "김밥", 2500),
    RAMEN(new MenuNumber("2"), "라면", 3000),
    TTEOKBOKKI(new MenuNumber("3"), "떡볶이", 4000),
    PORKCUTLET(new MenuNumber("4"), "돈까스", 5000);

    private final String name;
    private final int price;
    private final MenuNumber menuNumber;

    Menu(MenuNumber menuNumber, String name, int price) {
        this.menuNumber = menuNumber;
        this.name = name;
        this.price = price;
    }

    /*......................*/
    
    public static Menu[] getAll() {
        return Menu.values();
    }


    /*......................*/
}
   
public class MenuNumber {
   public MenuNumber(String menuNumber) {
        validateFormmat(menuNumber);
        validateExistMenu(menuNumber);
        
        this.menuNumber = menuNumber;
    }

/*......................*/

    private void validateExistMenu(String command) {
        if (!Menu.isExist(Integer.parseInt(command))) {
            throw new IllegalArgumentException(INVALID_MENU_NUMBER);
        }
    }
}

Enum은 최초 접근시 초기화 되는데, 초기화 되는 과정에서 순환 참조가 발생해서 생긴 오류였다.


1. Menu Enum을 초기화 하는 과정에서 MenuNumber를 생성함
2. MenuNumber를 생성하는 과정에서 validation을 위해 Enum의 Static Method를 사용
3. 해당 Method는 Menu.values() 메소드를 사용 중인데,
4. Enum value들이 초기화가 되지 않았기에 오류가 발생한 것이다.


이는 static 초기화 블록을 사용해서 해결이 가능하다.
static 초기화 블록에서 순환참조가 발생하는 객체를 생성해서 넣어준다.
처음 접근 시 명시적 초기화를 통해 Enum 상수들을 생성하고, static 초기화 블록에서 객체를 생성해서 넣어주는 시점에는 MenuNumber에서 접근할 Enum 상수들이 존재하기 때문에 오류가 발생하지 않는다.
사실은 그냥 설계를 개떡같이 했기에 이런 문제가 발생하지 않았을까 싶다.

시도해 본 것

  • static 초기화 블록을 통해 해결함

알게된 것

  • JVM에서 Enum의 로드 시점 -> 최초 접근시 초기화된다.
  • enum 상수는 static final이다.
  • 클래수 변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 클래스 초기화 블록(static 블록)
  • cf) 인스턴수 변수 초기화 순서 : 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자

출처

profile
hello dev!!

0개의 댓글