Post

Java Enum

Java Enum

소프트웨어를 개발하다 보면 상태(state) 나 카테고리(category) 를 문자열(String)로 표현하는 경우가 흔합니다. 예를 들어 회원 등급을 “BASIC”, “GOLD”, “DIAMOND” 같은 문자열로 다루는 경우를 말합니다. 이 방식은 오타나 잘못된 입력을 컴파일 단계에서 걸러낼 수 없다는 단점이 있습니다

본 글에서는 문자열 기반 접근법이 왜 위험한지, 이를 해결하기 위해 타입 안전 열거형 패턴(Type‑Safe Enum Pattern)과 자바 enum 을 어떻게 활용할 수 있는지 살펴보겠습니다.

String으로 표현했을 때의 문제점

  1. 타입 안정성 부족
    1. 오타로 인한 오류 “GOLD” 대신 “GLOD” 를 입력해도 컴파일러는 모릅니다.
    2. 잘못된 값 허용 “VIP” 처럼 정의되지 않은 값도 런타임까지 살아남습니다.
  2. 데이터 일관성 저하
    1. 대소문자 및 포맷이 제각각 “gold”, “Gold”, “GOLD” …
  3. 컴파일 시점 검증 불가
    1. 모든 검증이 런타임으로 미뤄져 디버깅 난이도가 상승합니다.
1
2
3
4
5
6
public int discount(String grade, int price) {
    if ("BASIC".equals(grade)) return price * 10 / 100;
    if ("GOLD".equals(grade))  return price * 20 / 100;
    if ("DIAMOND".equals(grade)) return price * 30 / 100;
    throw new IllegalArgumentException("Invalid grade: " + grade);
}

Type‑Safe Enum Pattern

아이디어: 미리 정의된 한정된 객체만 제공하고, 외부에서는 그 객체만 사용하도록 강제합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Grade {
    private final int discountPercent;
    private Grade(int discountPercent) { // 외부 생성 차단
        this.discountPercent = discountPercent;
    }

    public int discount(int price) {
        return price * discountPercent / 100;
    }

    // 미리 준비한 정적 인스턴스만 공개
    public static final Grade BASIC   = new Grade(10);
    public static final Grade GOLD    = new Grade(20);
    public static final Grade DIAMOND = new Grade(30);
}
  • 타입 안정성: Grade 타입만 받을 수 있어 잘못된 값이 컴파일 단계에서 차단됩니다.
  • 일관성 보장: 미리 정의된 세 인스턴스만 존재하므로 데이터가 흔들리지 않습니다.
  • 생성자, 필드, 등 작성해야 하는 코드가 많습니다.

Java Enum 사용

1
2
3
4
5
6
7
8
9
10
11
12
public enum Grade {
    BASIC(10), GOLD(20), DIAMOND(30);

    private final int discountPercent;
    Grade(int discountPercent) {
        this.discountPercent = discountPercent;
    }

    public int discount(int price) {
        return price * discountPercent / 100;
    }
}
  • 코드 간결성: 몇 줄이면 타입 안전 열거형 기능 완성.
  • 컴파일 타임 검증: Grade 외 다른 타입은 전달 자체가 불가.
1
int pay = grade.discount(totalPrice); // grade 는 오직 BASIC/GOLD/DIAMOND 중 하나

Enum Method

메서드설명
values()모든 상수를 Grade[] 로 반환
valueOf(String name)이름에 해당하는 상수를 반환, 이름 불일치 시 IllegalArgumentException
name()선언된 상수 이름 문자열 반환
ordinal()선언 순서(0‑base) 반환 — 위치 변경 시 값이 바뀌므로 주의!
toString()기본은 name() 과 동일, 필요하면 오버라이딩 가능

TIP: ordinal() 은 로직에 사용하지 마세요. 새로운 등급을 중간에 끼워 넣으면 모든 인덱스가 변경되어 예기치 못한 버그를 유발합니다.

static import 로 가독성 향상

1
2
3
import static com.example.Grade.*;

Grade grade = GOLD; // 클래스명 없이 읽기 쉬운 코드

맺음말

문자열은 편리하지만 타입 안정성데이터 일관성 을 담보해 주지 않습니다. 반면 enum 은 컴파일 타임에 잘못된 값을 차단하고, 코드 가독성과 유지 보수성을 크게 향상시킵니다.

다음 프로젝트에서 상태나 카테고리를 다룰 때, 아직도 String 대신 enum 사용해보시는 것을 추천드립니다.

This post is licensed under CC BY 4.0 by the author.