목차

Java enum

name() 기반 조회가 많을 경우

public enum MyEnum {
    BAR,
    BAZ;
    // 외부에서는 MAP에 접근이 불가능해야한다.
    private static final Map<String, MyEnum> MAP = Stream.of(MyEnum.values()).collect(Collectors.toMap(Enum::name, Function.identity()));
 
    public static MyEnum fromName(String name){
        return MAP.get(name);
    }
}

https://stackoverflow.com/a/43664038/1051402

자기 참조 enum - Self referential enum

enum이 enum 생성자에서 동일 enum의 다른 값을 참조해야하는 경우가 발생할 수 있는데, 아직 초기화가 안된 다른 값을 참조하는 것은 문법적으로 불가하다. 이를 해결하는 여러가지 방법이 있다. java - Self referential enum with immutable parameters - Stack Overflow

abstract method 구현

public enum Flippable {
  A {
    public Flippable flip() { return Z; }
  }, B {
    public Flippable flip() { return Y; }
  }, Y {
    public Flippable flip() { return B; }
  }, Z {
    public Flippable flip() { return A; }
  };
  // 아래 추상 메소드를 각 enum 에서 직접 구현한다.
  public abstract Flippable flip();
}

static loading

정적 초기화를 사용할 수도 있다. 그러나 이 경우에 새로운 enum이 추가될 경우 빠뜨린 값이 있을 경우가 있다. 이에 대해 정적 초기화 구문에서 validation을 해주는 코드를 넣는 것이 좋을 것 같다.

public enum Flippable {
    A, B, Z, Y;
 
    static {
        A.opposite = Z;
        B.opposite = Y;
        Y.opposite = B;
        Z.opposite = A;
        // 모두 올바르게 값 설정이 되었는지 검증
        for (Flippable f : Flippable.values()) {
            if (f.flip().flip() != f) {
                throw new IllegalStateException("Flippable " + f + " inconsistent.");
            }
        }
    }
 
    public Flippable flip() {
        return opposite;
    }
 
    private Flippable opposite;
 
}

static loading with EnumMap

정적 로딩을 하되 EnumMap을 사용한다.

public enum Flippable 
{
  A, B, Y, Z;
 
  // 외부에서 접근, 변경 불가능하도록 private으로 선언.
  private static final Map<Flippable, Flippable> opposites;
 
  static {
    opposites = new EnumMap<>(Flippable.class);
    opposites.put(A, Z);
    opposites.put(B, Y);
    opposites.put(Y, B);
    opposites.put(Z, A);
 
    // 모두 올바르게 값 설정이 되었는지 검증
    for (Flippable f : Flippable.values()) {
      if (f.flip().flip() != f) {
        throw new IllegalStateException("Flippable " + f + " inconsistent.");
      }
    }
  }
 
  public Flippable flip() {
    return opposites.get(this);
  }
}

문자열 사용

생성자에서 enum이 아닌 enum을 나타내는 문자열을 받아서 나중에 메소드 호출시 이것을 enum 값으로 변경해주는 방법도 있다. 별로 추천하고 싶지 않음.