[Effective Java 3/E] ITEM 35. ordinal 메서드 대신 인스턴스 필드를 사용하라

    Effective Java 표지. Source : https://blog.insightbook.co.kr/

    Enum 클래스는 해당 상수가 Enum 타입에서 몇 번째 상수인지 리턴하는 ordinal 메서드를 제공한다.

    그러나 사용하지 않아야 한다.

     

    예제1 : 합주단의 종류

    public enum Ensemble {
            SOLO, DUET, TRIO, QUARTET, QUINTET, 
            SEXTET, SEPTET, OCTET, NONET, DECTET;
    
            public int numberOfMusicians() { return ordinal() + 1; }
    }

     

    쓰지 말아야 하는 이유

    1. 상수 선언 순서를 바꾸면 ordinal()은 오동작한다.
    2. 선언 순서에 기반해 동작하는 ordinal() 입장에선 당연하다.
    3. 이미 사용중인 정수와 똑같은 값을 가지는 상수는 만들 수 없다.
    4. 8중주는 8명이서 연주한다(octet). 그러나 복4중주(double quartet) 또한 8명이서 연주하는데 이를 표현할 방법이 없다.
    5. 값을 중간에 비워둘 수도 없다.
    6. dummy 상수를 넣어 순서를 맞추는 방법도 있지만 굉장히 비효율적이다.
    7. API User를 위해 구현된 메서드가 아니다.
    8. Enum API 문서에 명시된 바로는 EnumSet과 EnumMap과 같이 열거타입 기반의 범용 자료구조에 쓸 목적으로 설계되었다고 한다.

     

    해결법

    열거 타입 상수에 연결된 값은 ordinal 메서드로 얻지말고, 인스턴스 필드에 선언한다.

     

    예제2: 합주단의 종류 개선

    public enum Ensemble {
        SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5),
        SEXTET(6), SEPTET(7), OCTET(8), DOUBLE_QUARTET(8),
        NONET(9), DECTET(10), TRIPLE_QUARTET(12);
    
        private final int numberOfMusicians;
        Ensemble(int size) { this.numberOfMusicians = size; }
        public int numberOfMusicians() { return numberOfMusicians; }
    }

     

     

    댓글