비트 필드 (bit masking 이라고도 함) 은 보통 하나의 int 형 변수에 2의 제곱마다 특정한 의미를 가지게 하여 그 의미들을 중첩해서 나타내도록 하는 기법 중 하나다. 이는 메모리에 값을 저장할 때 bit 단위로 저장하는 컴퓨터의 특징 때문에 메모리 효율적이고, 비교적 빠르게 저장할 수 있다는 장점을 가지고 있다.
예전에야 메모리 한 비트가 중요해 이런식으로 특정 설정값을 저장해 사용했다고 하지만, 요즘에는 여러 이유 때문에 메모리 공간이 넉넉한 환경에서는 보통 사용되지 않는다.
public class Text {
public static final int STYLE_BOLD = 1 << 0;
public static final int STYLE_ITALIC = 1 << 1;
public static final int STYLE_UNDERLINE = 1 << 2;
public static final int STYLE_STRIKETHROUGH = 1 << 3;
public void applyStyles(int styles) { ... }
}
위에 코드에서 알 수 있듯이 bold, italic, underline, strikethrough 처럼 컴퓨터에서 나타나는 text 에서 중첩될 수 있는 설정값들을 어떻게 설정할 것인가 생각하면 boolean 형 4개를 하나의 클래스에서 설정하는 방법을 생각할 수 있겠지만,
위에처럼 더 효율적으로 1111(2진법) 으로 나타내 15라는 정수값 하나로 해당 글자의 스타일을 저장할 수 있다.
text.applyStyles(STYLE_BOLD | STYLE_ITALIC);
bit field 를 이용하여 text 의 스타일을 지정하는 방법은 or 비트 연산자를 이용하여 값들을 중첩시킬 수 있다.
하지만 이 비트필드는 정수 열거 상수의 단점을 그대로 지니며, 아래와 같은 추가적인 문제도 안고 간다.
java.util 패키지의 Enumset 클래스는 열거타입 상수의 값으로 구성된 집합을 효과적으로 표현해준다. Set 인터페이스를 완벽히 구현하며, 타입안전하고, 다른 Set 구현체와도 함께 사용할 수 있다.
또한 내부적으로 비트 벡터로 구현되어있어, 원소가 64개 이하라면 long 변수 하나로 표현되는 비트필드와 비견되는 성능을 보여준다.
쉽게 말해서 가독성 문제를 해결해주고, 원소를 얼마나 가지느냐에 따라 bit field 를 알아서 설정해주는 듯한 기능을 하는 Set 구현체이다.
public class Text {
public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }
public void applyStyles(Set<Style> styles) {...}
}
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));