Effective Java : 아이템 35. ordinal() 대신 인스턴스 필드를 사용하라

    아이템 35. enum에서 ordinal() 대신 인스턴스 필드를 사용하라 

    enum은 내부에서 사용할 수 있도록 ordinal() 메서드가 제공된다. ordinal() 메서드는 enum 내부에 선언된 열거형 상수의 위치를 알려주는 메서드다. 그렇지만 가급적이면 ordinal()을 사용하는 것을 피해야한다. 

    // 이런 문제가 있음.
    // 1. SIX = 6임. 그런데 six도 추가하고 싶다면?
    // 2. Number 열거형에서 3을 제외하고 싶다면?
    public enum NumberWrong {
        ONE, TWO, THREE, FOUR, FIVE, SIX;
    
        public int getCount() {
            return ordinal() + 1;
        }
    }

    ordinal()을 이용하려고 하는 상황을 가정해보자. 이 때 이런 한계가 존재한다.

    • 선언된 열거형 상수의 위치가 바뀔 때 → 의미가 달라짐. 
    • 같은 의미를 가지는 열거형 상수를 추가하고 싶을 때 → 불가능함. 
    • 중간에 있는 값을 사용하고 싶지 않을 때 → 더미 상수를 넣어야 함. 

     

    선언된 열거형 상수의 위치가 바뀔 때

    현재는 ONE = 1, TWO = 2를 반환할 것이다. 그런데 TWO, ONE 순서대로 선언되어 있는 경우 TWO = 1, ONE =2 를 반환하게 될 것이다. 이런 변경에 취약해진다. 

     

    같은 의미를 가지는 열거형 상수를 추가하고 싶을 때

    현재는 SIX = 6이라는 의미를 가진다. 그런데 six(소문자)라는 값도 열거형 상수도 추가해서 6이라는 값을 가지도록 만들고 싶은 경우가 있다. 이럴 때는 ordinal()을 사용해서는 문제를 해결할 수 없다. 

     

    중간에 있는 값을 사용하고 싶지 않을 때 

    enum Number를 이용해 1,3,5의 값만 표현하고 싶다고 가정해보자. ordinal()을 이용한다면 2,4를 표현하는 위치에 더미 값을 넣어줘야한다. 이렇게 하면 코드가 지저분해진다. 

     

    해결방법 → ordinal() 대신 인스턴스 필드를 사용하자. 

    이런 이유 때문에 열거형 상수의 의미를 부여하기 위해 ordinal()을 사용하는 것은 좋지 않은 방법이다. 해결 방법으로는 열거형 상수가 각각의 의미를 가질 수 있도록 인스턴스 필드에 저장해서 사용하도록 한다. 

    // ITEM 35 : ordinal()은 가급적이면 사용하지 마라. 필요한 값은 생성자에 넣고 사용해라.
    public enum NumberGood {
        ONE(1),
        TWO(2),
        THREE(3),
        FOUR(4),
        FIVE(5),
        SIX(6);
    
        private final int number;
    
        NumberGood(int number) {
            this.number = number;
        }
    
        public int number() {
            return this.number;
        }
    }

    댓글

    Designed by JB FACTORY