35. ordinal 메서드 대신 인스턴스 필드를 사용하라
✅ 1. ordinal()이란?
ordinal()
은 enum 상수가 **정의된 순서(0부터)**에 따라 자동 부여되는 번호를 반환하는 메서드
enum Day {
MONDAY, TUESDAY, WEDNESDAY;
}
Day.MONDAY.ordinal(); // 0
Day.TUESDAY.ordinal(); // 1
enum이 자동으로 제공하는 메서드
상수 정의 순서에 의존하는 숫자
✅ 2. 왜 사람들이 ordinal()
을 쓰고 싶어할까?
ordinal()
을 쓰고 싶어할까?숫자 값이 필요할 때, 간단히
ordinal()
을 쓰면 편해 보이기 때문
예: 연주자 수 표현
public enum Ensemble {
SOLO, DUET, TRIO, QUARTET;
public int numberOfMusicians() {
return ordinal() + 1;
}
}
SOLO → 0 + 1 = 1명
DUET → 1 + 1 = 2명
✅ 처음엔 잘 동작하지만, 큰 함정이 숨어 있음
❌ 3. ordinal()의 위험성
🧨 문제 1: 선언 순서가 바뀌면 결과가 깨진다
public enum Ensemble {
SOLO, DUET, TRIO;
}
→ DUET.ordinal() == 1
// 나중에 순서 바꿈
public enum Ensemble {
DUET, SOLO, TRIO;
}
→ DUET.ordinal() == 0
❗
→ 결과가 바뀌어버림!
🧨 문제 2: 중간값을 비워둘 수 없음
public enum Ensemble {
SOLO, DUET, TRIO, ..., DECTET, TRIPLE_QUARTET;
public int numberOfMusicians() {
return ordinal() + 1;
}
}
TRIPLE_QUARTET.ordinal() = 11 → 12명
그런데 나중에
ELEVEN_TET
(11명)를 추가하면?중간에 끼워야 하므로 순서가 깨지고 로직이 오동작함
🧨 문제 3: 같은 값을 가진 다른 이름 표현 불가
OCTET
도 8명DOUBLE_QUARTET
도 8명
OCTET.ordinal() = 7 → 8명
DOUBLE_QUARTET.ordinal() = 8 → 9명 ❌
→
ordinal()
값이 달라서, 같은 의미의 상수를 표현할 수 없음
✅ 4. 해결책: 명시적인 필드를 사용하자
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),
ELEVEN_TET(11), TRIPLE_QUARTET(12);
private final int musicians;
Ensemble(int musicians) {
this.musicians = musicians;
}
public int numberOfMusicians() {
return musicians;
}
}
✅ 장점
순서 바뀜
❌ 값도 바뀜
✅ 값 고정
중간 값 없음
❌ 강제로 더미 추가
✅ 자유롭게 비움
같은 값 표현
❌ 불가능
✅ 가능
유지보수
❌ 위험
✅ 안전하고 명확
✅ 5. 요약
ordinal()
은 enum 내부의 순서를 위한 유틸 메서드일 뿐, 그 값을 의미 있는 로직에 사용하는 것은 매우 위험한 습관입니다.
✅ 대신, 의미 있는 값은 명시적인 인스턴스 필드로 정의하세요.
ordinal()
은 편해 보이지만, 로직에서 쓰면 쉽게 깨지는 폭탄 같은 존재입니다. 진짜 의미 있는 숫자는 필드에 직접 저장하는 게 안전합니다.
발표 자료
https://byumm315.atlassian.net/wiki/external/MWJkNjhmOGI4NWM1NDFhYmFmMDQ0YzBkZDY5ZWE0ODg
Last updated