아이템 37 : ordinal 인덱싱 대신 EnumMap을 사용하라
이따금 배열이나 리스트에서 원소를 꺼낼 때 ordinal 메서드로 인덱스를 얻는 코드가 있다.
ordinal()을 배열 인덱스로 사용할 경우 동작은 하지만 문제가 발생할 것이다. 배열은 제네릭과 호환되지 않으니 비검사 형번환을 수행해야 하고 깔끔히 컴파일되지 않을 것이다.
이를 해결할 수 있는 방안이 있다. 여기서 배열은 실질적으로 열거 타입 상수를 값으로 매핑하는 일을 한다. 그러니 Map을 사용할 수 있다.
열거 타입을 키로 사용하도록 설계된 아주 빠른 Map 구현체가 존재한다. 바로 EnumMap이다.
EnumMap을 사용하면 ordinal을 쓸때보다 짧고 명료하고 안전하다.
안전하지 않은 형변환은 쓰지 않고, 맵의 키인 열거 타입이 그 자체로 출력용 문자열을 제공하니 출력 괄과에 직접 레이블을 달 일도 없다. 나아가 배열 인덱스를 계산하는 과정에서 오류가 날 가능성도 원천봉쇄된다. EnumMap의 성능이 ordinal을 쓴 배열에 비견되는 이유는 그 내부에서 배열을 사용하기 때문이다. 내부 구현 방식을 안으로 숨겨서 Map의 타입 안전성과 배열의 성능을 모두 얻어낸 것이다. 여기서 EnumMap의 생성자가 받는 키 타입의 Class 객체는 한정적 타입 토큰으로, 런타임 제네릭 타입 정보를 제공한다.
핵심 정리
배열의 인덱스를 얻기 위해 ordinal을 쓰는 것은 일반적으로 좋지 않으니, 대신 EnumMap을 사용하라. 다차원 관계는
EnumMap<... , EnumMap<...>>으로 표현하라. "애플리케이션 프로그래머는 Enum.ordinal을 (웬만해서는) 사용하지 말아야 한다(아이템 35)"는 일반 원칙의 특수한 사례다.
'언어 > JAVA' 카테고리의 다른 글
[Effective Java] 명명 패턴보다 애너테이션을 사용하라 (0) | 2020.04.01 |
---|---|
[Effective Java] 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라 (0) | 2020.03.31 |
[Effective Java] 비트 필드 대신 EnumSet을 사용하라 (0) | 2020.03.29 |
[Effective Java] ordinal 메서드 대신 인스턴스 필드를 사용하라 (0) | 2020.03.28 |
[Effective Java] int 상수 대신 열거 타입을 사용하라 (0) | 2020.03.27 |