어제 오늘 내일

[Java] Enum 사용법 총정리 본문

IT/Java

[Java] Enum 사용법 총정리

hi.anna 2026. 2. 17. 23:33

자바 개발을 하다 보면 final static String... 처럼 상수를 정의해서 쓰는 경우가 많습니다. 하지만 단순히 값을 나열하는 것보다 Enum(열거형)을 사용하면 코드의 안전성과 가독성을 획기적으로 높일 수 있습니다.

오늘은 자바 Enum을 단순한 목록이 아닌, 데이터와 로직을 가진 강력한 객체로 활용하는 방법을 단계별로 정리해 드립니다.


1. 왜 Enum을 써야 할까요?

과거에는 상수를 이렇게 정의했습니다.

public static final int MONDAY = 1;
public static final int TUESDAY = 2;
// ...
int today = 1; // 1이 월요일인지, 1월인지 코드로만 봐선 알 수 없음

Enum의 장점:

  1. 코드가 명확해집니다: 1 대신 Week.MONDAY를 쓰니 의미가 바로 보입니다.
  2. 타입 안전성(Type Safety): 엉뚱한 값(예: 100)이 들어가는 것을 컴파일 단계에서 막아줍니다.
  3. 관련 로직 응집: 상수와 관련된 데이터나 계산 로직을 한 클래스 안에 모을 수 있습니다.

Level 1. 기초 사용법 (단순 목록)

가장 기본적인 형태입니다. 요일, 계절, 색상 등 단순한 목록을 정의할 때 사용합니다.

public enum Week {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}

// 사용 예시
Week today = Week.FRIDAY;

if (today == Week.SUNDAY) {
    System.out.println("오늘은 쉬는 날!");
}

Level 2. 데이터 연결하기 (필드와 생성자) ★

실무에서는 "상수 코드""사용자에게 보여줄 텍스트"를 연결해야 할 때가 많습니다.
(예: DB엔 READY로 저장하고, 화면엔 "준비 중"으로 출력)

Enum은 클래스이기 때문에 필드(Field)생성자(Constructor)를 가질 수 있습니다.

import lombok.Getter;

@Getter // Lombok으로 Getter 자동 생성
public enum OrderStatus {

    // 1. 상수 정의 (괄호 안에 필드 값을 넣음)
    READY("ORD_001", "상품 준비 중"),
    SHIPPED("ORD_002", "배송 시작"),
    DELIVERED("ORD_003", "배송 완료"),
    CANCELED("ORD_999", "주문 취소");

    // 2. 필드 정의 (상수와 연결될 데이터)
    private final String code;
    private final String description;

    // 3. 생성자 (Enum의 생성자는 무조건 private입니다)
    OrderStatus(String code, String description) {
        this.code = code;
        this.description = description;
    }
}

[사용 방법]

public void printStatus() {
    OrderStatus status = OrderStatus.SHIPPED;

    System.out.println(status.name());        // "SHIPPED" (Enum 이름)
    System.out.println(status.getCode());     // "ORD_002" (DB 저장용 코드)
    System.out.println(status.getDescription()); // "배송 시작" (화면 출력용)
}

Level 3. 데이터로 Enum 찾기 (Reverse Lookup)

DB에서 "ORD_002"라는 문자열을 읽어왔을 때, 이를 다시 자바의 OrderStatus.SHIPPED 객체로 변환해야 한다면 어떻게 할까요?

Arrays.stream을 활용하면 우아하게 구현할 수 있습니다.

import java.util.Arrays;

public enum OrderStatus {
    // ... (위와 동일) ...

    // ★ 코드값으로 Enum 찾기 (static 메서드)
    public static OrderStatus findByCode(String code) {
        return Arrays.stream(OrderStatus.values()) // 모든 Enum 값을 스트림으로
                .filter(status -> status.code.equals(code)) // 코드가 같은 것 필터링
                .findAny()
                .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 주문 코드입니다: " + code));
    }
}

// 사용 예시
OrderStatus result = OrderStatus.findByCode("ORD_002"); // OrderStatus.SHIPPED 반환

Level 4. 로직(함수) 포함하기 (Strategy Pattern)

심화 과정입니다. Enum 상수마다 서로 다른 동작을 수행해야 한다면?
if-elseswitch 문을 잔뜩 쓰는 대신, Enum 안에 람다식(Lambda)을 넣어 해결할 수 있습니다.

[계산기 예제]

import java.util.function.BiFunction;

public enum Calculator {
    // 람다식을 파라미터로 넘김
    PLUS((a, b) -> a + b),
    MINUS((a, b) -> a - b),
    MULTIPLY((a, b) -> a * b),
    DIVIDE((a, b) -> a / b);

    // 두 개의 인자를 받아 하나를 리턴하는 함수 인터페이스
    private final BiFunction<Integer, Integer, Integer> expression;

    Calculator(BiFunction<Integer, Integer, Integer> expression) {
        this.expression = expression;
    }

    public int calculate(int a, int b) {
        return expression.apply(a, b);
    }
}

[사용 예시]

// if (type == "PLUS") ... else if ... (X) 지저분한 분기문 삭제!
int result = Calculator.PLUS.calculate(10, 20); // 30

💡 요약

자바의 Enum은 단순한 문자열 배열이 아닙니다.

  1. Level 1: 단순 목록 관리에 사용하여 가독성을 높인다.
  2. Level 2: 필드를 추가하여 코드와 설명을 한곳에서 관리한다.
  3. Level 3: findBy 메서드를 만들어 DB 값과 쉽게 변환한다.
  4. Level 4: 함수를 내장하여 if-else 로직을 제거한다.

이제 Enum을 단순한 상수가 아닌 강력한 도구로 활용해 보세요! 🚀
 
 

반응형
Comments