[교재 EffectiveJava] 아이템 35. ordinal 메서드 대신 인스턴스 필드를 사용하라

반응형
728x90
반응형

ordinal 메서드의 문제점

대부분의 열거 타입 상수는 하나의 정숫값에 대응된다. 그리고 모든 열거 타입은 해당 상수가 그 열거 타입에서 몇번째 위치인지를 반환하는 ordinal 메서드를 제공한다. 

 

예제 Ensemble.java
package com.java.effective.item35;

public enum Ensemble {
    SOLO, DUET, TRIO, QUARTET; // ordinal() : 선언 순서 대로 정수값 반환 

    public int numberOfMusicians() {
        return ordinal() + 1;
    }
}

 

Enum.java 의 ordinal()
public final int ordinal() {
    return ordinal;
}

 

이는 아주 위험한 코드다. 상수 선언 순서를 바꾸는 순간 numberOfMusicians 가 오동작하며, 이미 사용중인 정수와 값이 같은 상수는 추가할 방법이 없다. 

 

또한, 값을 중간에 비워둘 수도 없다. 12명이 연주하는 3중 4중주를 추가한다고 해보자. 그러려면 중간 11명짜리 상수도 채워야하는데, 11명으로 구성된 연주를 일컫는 이름이 없다. 이런 경우 쓰이지않을 더미 상수를 같이 추가해야만 한다. 코드가 깔끔하지 못하고, 쓰이지않는 값이 많아질수록 실용성이 떨어진다.

 

 

해결책

열거 타입 상수에 연결된 값은 ordinal 메서드로 말고, 인스턴스 필드에 저장하자.

package com.java.effective.item35;

public enum Ensemble2 {
    SOLO(1), 
    DUET(2), 
    TRIO(3), 
    QUARTET(4);

    private final int numberOfMusicians;
    Ensemble2(int size) {
        this.numberOfMusicians = size;
    }
    
    public int numberOfMusicians() {
        return numberOfMusicians;
    }
}

 

Enum.java 의 ordinal() 메서드 설명
Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial constant is assigned an ordinal of zero). Most programmers will have no use for this method. It is designed for use by sophisticated enum-based data structures, such as java.util.EnumSet and java.util.EnumMap.
Returns:
the ordinal of this enumeration constant
public final int ordinal() {
    return ordinal;
}

 

대부분의 개발자는 이 메서드를 쓸 일이 없다. 이 메서드는 EnumSet과 EnumMap 같이 열거 타입 기반의 범용 자료구조에 쓸 목적으로 설계되었다고 적혀있다. 따라서 이런 용도가 아니라면, ordinal 메서드를 사용하지말자.

 

 

반응형

Designed by JB FACTORY