이펙티브 자바, 쉽게 정리하기 - item 35. ordinal 메서드 대신 인스턴스 필드를 사용하라
잘못 사용한 예
enum Ensemble {
SOLO, DUET, TRIO, QUARTET, QUINTET,
SEXTET, SEPTET, OCTET, NONET, DECTET;
public int numberOfMusicians() {
return ordinal() + 1;
}
}
@Test
public void ensembleTest() {
Ensemble solo = Ensemble.SOLO;
System.out.println("solo = " + solo);
System.out.println("solo.numberOfMusicians() = " + solo.numberOfMusicians());
}
ordinal()
의 값을 활용하여 오케스트라 단원의 수를 출력하는 메서드를 구현했다.- 하지만 이는 잘못된 구현이다.
ordinal()
은EnumSet
,EnumMap
과 같이 열거타입 기반의 범용 자료구조에 쓰일 목적으로 설계되었다.- 만일 중간에 다른 상수라도 추가되면
numberOfMusicians()
는 혼란에 빠진다.
- 만일 중간에 다른 상수라도 추가되면
ordinal()
을 사용하지 말고, 각 인스턴스의 필드 값으로 저장해두자.
EnumSet
에서의 ordinal()
활용
public boolean contains(Object e) {
if (e == null)
return false;
Class<?> eClass = e.getClass();
if (eClass != elementType && eClass.getSuperclass() != elementType)
return false;
return (elements & (1L << ((Enum<?>)e).ordinal())) != 0;
}
EnumSet
은ordinal()
의 값을 bit-vector로 이용하여 중복 판단을 한다.
EnumMap
에서의 ordinal()
활용
public boolean containsKey(Object key) {
return isValidKey(key) && vals[((Enum<?>)key).ordinal()] != null;
}
EnumMap
은ordinal()
의 값을 값 배열의 인덱스로 활용한다.
모범답안
enum Ensemble {
SOLO(1)
, DUET(2)
, TRIO(3)
, QUARTET(4)
, QUINTET(5)
, SEXTET(6)
, SEPTET(7)
, OCTET(8)
, NONET(9)
, DECTET(10);
private final int numberOfMusicians;
Ensemble(int numberOfMusicians) {
this.numberOfMusicians = numberOfMusicians;
}
public int numberOfMusicians() {
return numberOfMusicians;
}
}
@Test
public void ensembleTest() {
Ensemble solo = Ensemble.SOLO;
System.out.println("solo = " + solo);
System.out.println("solo.numberOfMusicians() = " + solo.numberOfMusicians());
}
- 이제 순서가 아무리 뒤죽박죽이 되어도, 다른 상수가 추가되어도 상관 없다.
반응형
'Java > 이펙티브 자바' 카테고리의 다른 글
이펙티브 자바, 쉽게 정리하기 - item 37. ordinal 인덱싱 대신 EnumMap을 사용하라 (0) | 2022.02.24 |
---|---|
이펙티브 자바, 쉽게 정리하기 - item 36. 비트 필드 대신 EnumSet을 사용하라 (0) | 2022.02.24 |
이펙티브 자바, 쉽게 정리하기 - item 34. int 상수 대신 열거 타입을 사용하라 (0) | 2022.02.24 |
이펙티브 자바, 쉽게 정리하기 - item 33. 타입 안전 이종 컨테이너를 고려하라 (0) | 2022.01.24 |
이펙티브 자바, 쉽게 정리하기 - item 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라 (0) | 2022.01.24 |