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 상수들이 존재하기 때문에 오류가 발생하지 않는다.
사실은 그냥 설계를 개떡같이 했기에 이런 문제가 발생하지 않았을까 싶다.