이펙티브 자바 #item36 비트필드 대신 EnumSet을 활용하라

임현규·2023년 2월 20일
0

이펙티브 자바

목록 보기
36/47
post-thumbnail

비트 필드와 상수를 활용한 예와 문제점

자바에서 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) {}
}

우선 비트 필드의 장점은 비트 연산을 통해 합집합과 교집합과 같은 연산을 매우 효율적으로 수행할 수 있다. 그러나 정수 열거 상수의 단점을 그대로 가지고 있다.

정수 열거 상수 단점

  • 타입 안전을 보장할 수 없다.
  • 표현력이 좋지 않다.
  • 정수 열거 패턴을 위한 별도 이름공간(namespace)를 지원하지 않는다.
  • 문자열로 출력하기가 까다롭다.
  • 같은 정수 열거 그룹에 속한 모든 상수를 순회하는 방법이 마땅치 않다.

그리고 디버깅을 할 때 비트 필드 값이 그대로 출력된다면 이해하기가 어렵고 비트 필드 순회도 까다롭다. 그리고 API 작성시 미리 예측해서 32비트, 64비트를 선택해야하며, 또한 그 이상의 비트를 활용하기 어렵다는 점도 있다.

효과적인 대안 EnumSet

EnumSet은 Set 인터페이스를 활용해 구현되었고, 내부는 비트 벡터로 구현되었다. 원소가 총 64개 이하라면 EnumSet 전체를 long으로 표현하여 비트 필드에 비견되는 성능을 가지면서, 더욱 쉽게 API를 설계할 수 있다.

위의 코드를 EnumSet을 활용하면 다음과 같다.

class Text {
	public enum Style {BOLD, ITALIC, UNDERINE, STRIKETHROUGH}
    
    public void applyStyle(Set<Style> styles) {}
}

열거를 집합으로 표현해야 한다면 EnumSet을 활용하자.

profile
엘 프사이 콩그루

0개의 댓글