자바에서 Reflection에 활용되는 Modifier의 클래스를 보면 Modifier는 비트를 활용해서 해당 객체가 가지고 있는 여러 특성을 잘 표현한다.
Modifier는 비트 포지션을 활용하여 실제로 객체가 가진 여러 특성을 표현한다.
그러나 이런 방법은 현대적인 방법이 아니라고 한다.
왜 현대적이지 않은 것일까?
class Text {
public static final int STYLE_BOLD = 1 << 0;
pubiic static final int STYLE_ITALIC = 1 << 1;
pubiic static final int STYLE_UNDERLINE = 1 << 2;
pubiic static final int STYLE_STRIKETHROUGH = 1 << 3;
public void applyStyle(int style) {}
}
우선 비트 필드의 장점은 비트 연산을 통해 합집합과 교집합과 같은 연산을 매우 효율적으로 수행할 수 있다. 그러나 정수 열거 상수의 단점을 그대로 가지고 있다.
정수 열거 상수 단점
그리고 디버깅을 할 때 비트 필드 값이 그대로 출력된다면 이해하기가 어렵고 비트 필드 순회도 까다롭다. 그리고 API 작성시 미리 예측해서 32비트, 64비트를 선택해야하며, 또한 그 이상의 비트를 활용하기 어렵다는 점도 있다.
EnumSet은 Set 인터페이스를 활용해 구현되었고, 내부는 비트 벡터로 구현되었다. 원소가 총 64개 이하라면 EnumSet 전체를 long으로 표현하여 비트 필드에 비견되는 성능을 가지면서, 더욱 쉽게 API를 설계할 수 있다.
위의 코드를 EnumSet을 활용하면 다음과 같다.
class Text {
public enum Style {BOLD, ITALIC, UNDERINE, STRIKETHROUGH}
public void applyStyle(Set<Style> styles) {}
}
열거를 집합으로 표현해야 한다면 EnumSet을 활용하자.