35. ordinal 메서드 대신 인스턴스 필드를 사용하라


✅ 1. ordinal()이란?

ordinal()은 enum 상수가 **정의된 순서(0부터)**에 따라 자동 부여되는 번호를 반환하는 메서드

enum Day {
    MONDAY, TUESDAY, WEDNESDAY;
}

Day.MONDAY.ordinal();    // 0
Day.TUESDAY.ordinal();   // 1
  • enum이 자동으로 제공하는 메서드

  • 상수 정의 순서에 의존하는 숫자


✅ 2. 왜 사람들이 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;
    }
}

✅ 장점

문제
ordinal 방식
필드 방식

순서 바뀜

❌ 값도 바뀜

✅ 값 고정

중간 값 없음

❌ 강제로 더미 추가

✅ 자유롭게 비움

같은 값 표현

❌ 불가능

✅ 가능

유지보수

❌ 위험

✅ 안전하고 명확


✅ 5. 요약

ordinal()은 enum 내부의 순서를 위한 유틸 메서드일 뿐, 그 값을 의미 있는 로직에 사용하는 것은 매우 위험한 습관입니다.

✅ 대신, 의미 있는 값은 명시적인 인스턴스 필드로 정의하세요.


ordinal()은 편해 보이지만, 로직에서 쓰면 쉽게 깨지는 폭탄 같은 존재입니다. 진짜 의미 있는 숫자는 필드에 직접 저장하는 게 안전합니다.


발표 자료

https://byumm315.atlassian.net/wiki/external/MWJkNjhmOGI4NWM1NDFhYmFmMDQ0YzBkZDY5ZWE0ODg

Last updated