반응형

Enum에 정규식과 마스킹 메소드를 정의했는데, 정규식은 패턴에 따라 부분집합인 정규식도 간혹 존재한다. 나는 Enum에 작은 부분집합을 오름차순으로 정렬하였다.
패턴 검사할때도 Enum에 정의된 순서대로 검사가 되었으면 좋겠다고 생각했다. 각 Enum 요소에 Order 값을 추가해야하나 고민을 했는데, ordinal이라는 값이 있다는 것을 알게되어 활용했다.
📚 Enum의 ordinal()
1. Enum 정의 순서 = ordinal 값
Java Enum은 정의된 순서대로 자동으로 0부터 시작하는 인덱스가 부여된다. 그 인덱스가 바로 ordinal이다.
public enum BlackKeywordPattern {
PHONE(...), // ordinal() = 0
EMAIL(...), // ordinal() = 1
SSN(...), // ordinal() = 2
PASSPORT(...), // ordinal() = 3
ACCOUNT(...), // ordinal() = 4
CARD(...); // ordinal() = 5
}
2. ordinal() 메서드
public final int ordinal()
- Java의 모든 Enum이 가지는 메서드 (java.lang.Enum 클래스에서 상속)
- 정의된 순서를 정수로 반환
- final 메서드 - 오버라이드 불가능
- 자동으로 할당 - 개발자가 직접 설정하지 않음
3. 실제 동작 예시
// Enum 상수의 ordinal 값 확인
System.out.println(BlackKeywordPattern.PHONE.ordinal()); // 0
System.out.println(BlackKeywordPattern.EMAIL.ordinal()); // 1
System.out.println(BlackKeywordPattern.SSN.ordinal()); // 2
System.out.println(BlackKeywordPattern.PASSPORT.ordinal()); // 3
System.out.println(BlackKeywordPattern.ACCOUNT.ordinal()); // 4
System.out.println(BlackKeywordPattern.CARD.ordinal()); // 5
4. 정렬 원리
Collections.sort(sortedPatterns, new Comparator<BlackKeywordPattern>() {
@Override
public int compare(BlackKeywordPattern p1, BlackKeywordPattern p2) {
return Integer.compare(p1.ordinal(), p2.ordinal());
// PHONE(0) < EMAIL(1) < SSN(2) < ... 순서로 정렬됨
}
});
동작:
// 입력: [CARD(5), PHONE(0), EMAIL(1)]
// 정렬 과정:
// - CARD(5) vs PHONE(0) → PHONE이 작음 → PHONE 먼저
// - CARD(5) vs EMAIL(1) → EMAIL이 작음 → EMAIL 먼저
// 결과: [PHONE(0), EMAIL(1), CARD(5)]
5. Java 내부 구현
Java Enum의 실제 컴파일 결과:
// 우리가 작성한 코드:
public enum BlackKeywordPattern {
PHONE(...),
EMAIL(...),
SSN(...)
}
// 컴파일러가 생성하는 코드 (개념적):
public final class BlackKeywordPattern extends Enum<BlackKeywordPattern> {
public static final BlackKeywordPattern PHONE = new BlackKeywordPattern("PHONE", 0, ...);
public static final BlackKeywordPattern EMAIL = new BlackKeywordPattern("EMAIL", 1, ...);
public static final BlackKeywordPattern SSN = new BlackKeywordPattern("SSN", 2, ...);
private BlackKeywordPattern(String name, int ordinal, ...) {
super(name, ordinal); // ordinal 값이 여기서 설정됨
}
}
8. 대안 비교
| 방법 | 장점 | 단점 |
|---|---|---|
| ordinal() 사용 ✅ | 자동, 안전, 간단 | Enum 순서 변경 시 영향 |
| priority 필드 추가 | 순서와 독립적 | 수동 관리, 실수 가능성 |
| 하드코딩 | 명시적 | 중복 코드, 유지보수 어려움 |
결론
Enum 정의 순서 = ordinal 값 = 정렬 순서
ordinal을 이용하면 아래와 같은 순기능을 얻을 수 있다.
- 컴파일 타임에 결정 - 런타임에 변경 불가능
- 자동 할당 - 개발자 실수 방지
- 순서 보장 - Enum 정의 순서 = ordinal 순서
- 불변성 - final 메서드로 오버라이드 불가능
⚠️ Enum 순서를 바꾸면 ordinal도 변경되니 조심
// 변경 전
PHONE, // ordinal = 0
EMAIL, // ordinal = 1
SSN // ordinal = 2
// Enum 순서 변경 후
EMAIL, // ordinal = 0 (변경됨!)
PHONE, // ordinal = 1 (변경됨!)
SSN // ordinal = 2 (유지)
// 이 코드는:
return Integer.compare(p1.ordinal(), p2.ordinal());
// 이렇게 동작한다:
return Integer.compare(0, 1); // PHONE vs EMAIL → PHONE 먼저
return Integer.compare(0, 5); // PHONE vs CARD → PHONE 먼저
return Integer.compare(4, 5); // ACCOUNT vs CARD → ACCOUNT 먼저반응형
'개발 아카이브 > JAVA' 카테고리의 다른 글
| Spring 기본 - 게시판 만들기 (0) | 2025.09.21 |
|---|---|
| JAVA equals, hashCode 오버라이드시 instanceof와 getClass 차이 (0) | 2025.09.21 |
| Spring 기본 - DTO (Data Transfer Object) 패턴 (0) | 2025.09.20 |
| Spring 기본 - Service 계층 (0) | 2025.09.20 |
| Spring 기본 시작 - 세팅부터 CRUD API 까지 (2) | 2025.09.04 |
