들어가며
비트 필드는 정수 열거 상수의 단점을 그대로 지니며 비트 필드 값이 그대로 출력되면 해석하기 어려운 문제를 안고있다. 더불어 최대 몇 비트가 필요한지를 API 작성 시 미리 예측하여 적절한 타입(int, long)을 선택해야 한다. API를 수정하지 않고서는 비트필드를 수정할 수 없다. 덫붙히자면 책에서는 순회는 어렵다고 나왔지만 실은 간단하다. 그렇다고 비트필드를 쓰라는 말은 절대 아니다.
1 | while(bitField) { |
비트 필드를 사용하고 싶다면 EnumSet을 사용하자. EnumSet은 Set 인터페이스를 완벽히 구현하며, 타입 안전하고 다른 Set 구현체와도 함께 사용할 수 있다. 하지만 EnumSet의 내부는 비트 벡터로 구현되어 있다. 원소가 64개 이하라면 즉, 대부분의 경우에 EnumSet 전체를 long 변수 하나로 표현하여 비트 필드에 비견되는 성능을 보여준다. removeAll이나 retainAll과 같은 대량 작업은 비트를 효율적으로 처리하는 산술 연산을 구현했다. 그러면서도 비트를 직접 다룰 때 겪는 오류들에서 해방된다.
1 | /** |
EnumSet 인스턴스를 건네는 메소드의 파라미터는 인터페이스로 받는게 좋은 습관이다. 클라이언트가 다른 Set 구현체를 넘기더라도 처리가 가능해지기 때문이다.
1 | public void someMethod(Set<someEnumClass> enumClass) { ... } |