[Effective Java] ordinal 메소드 대신 인스턴스 필드를 사용하라

들어가며

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

1
2
3
4
5
6
7
8
public enum Ensemble {
SOLO, DUET, TRIO, QUARTET, QUINTET,
SEXTET, SEPET, OCTET, NONET, DECTET;

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

동작은 하지만 유지보수가 끔찍하다. 상수 선언 순서를 바꾸는 순간 numberOfMusicians는 오동작한다. 그리고 8중주(OCTET)가 있으니 복4중주(double quartet)는 추가할 수 없다. 그리고 3중 4중주(triple quartet)를 추가하려면 dummy 상수인 11번째 상수를 추가해야 한다.

해결책은 간단하다. 열거 타입 상수에 연결된 값은 ordinal 메소드가 아닌 인스턴스 필드에 연결하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public enum Ensemble {
SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5),
SEXTET(6), SEPET(7), OCTET(8), DOUBLE_QUARTET(8),
NONET(9), DECTET(10), TRIPLE_QUARTET(12);

private final int numberOfMusicians;

Ensemble(int numberOfMusicians) {
this.numberOfMusicians = numberOfMusicians;
}

public int numberOfMusicians() {
return this.numberOfMusicians;
}
}

Enum의 API 문서에는 orinal에 대해 EnumSet과 EnumMap 같이 열거 타입 기반의 범용 자료구조에 쓸 목적으로 설계되었다고 나와있다. 따라서 이런 용도가 아니라면 사용하지 말자.

Author: Song Hayoung
Link: https://songhayoung.github.io/2020/08/12/Languages/Effective%20JAVA/item35/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.