포스트

JAVA (5) - Enum

JAVA (5) - Enum

1. 개요

열거형(Enum, Enumeration)은 서로 관련이 있는 연관된 상수들의 집합을 정의하는 특수한 데이터 타입이다.

Java 5 이전에는 상수를 정의할 때 final static int 방식을 사용했지만, 이는 타입 안정성 문제나 가독성 저하를 유발했다. Enum을 활용하면 정해진 값 모음 이외의 잘못된 값이 들어오는 것을 컴파일 시점에 방지할 수 있고, 코드의 의미를 명확하게 전달할 수 있다.


2. Enum의 필요성: 기존 상수의 문제점

기존에 public static final을 이용해 상수를 정의하던 방식을 살펴보자.

1
2
3
4
5
6
7
8
9
public class DayConstant {
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
}

public class MonthConstant {
    public static final int JANUARY = 1;
}

이 방식은 두 가지 큰 문제점을 가진다.

  1. 타입 안전성(Type Safety) 부족: DayConstant.MONDAYMonthConstant.JANUARY는 둘 다 값이 1이므로 MONDAY == JANUARY 가 참이 되는 논리적 오류가 발생한다.
  2. 범위 외의 값 입력 방지 불가: 메서드의 매개변수로 DayConstant 중 하나를 받고 싶어도 타입이 int이기 때문에 정수 999 같은 엉뚱한 값이 전달되어도 컴파일 에러를 잡아내지 못한다.

3. Enum의 선언과 기본 사용법

Enum을 선언할 때는 class 대신 enum 키워드를 사용한다.

1
2
3
4
public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class EnumTest {
    public static void main(String[] args) {
        Day today = Day.FRIDAY;

        // 타입 안정성 보장: Day 타입에 속한 값만 대입할 수 있다.
        if (today == Day.FRIDAY) {
            System.out.println("금요일이다!");
        }

        // switch 문에서의 활용
        switch (today) {
            case MONDAY -> System.out.println("월요일");
            case FRIDAY -> System.out.println("금요일");
            default -> System.out.println("평일 또는 주말");
        }
    }
}


4. Enum이 제공하는 주요 메서드

Java의 모든 Enum은 내장 클래스인 java.lang.Enum을 상속받으므로 유용한 기본 메서드들을 사용할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Day today = Day.WEDNESDAY;

// 1. name(): Enum 상수의 이름을 문자열로 반환한다.
String name = today.name(); // "WEDNESDAY"

// 2. ordinal(): Enum 상수가 정의된 순서(0부터 시작)를 반환한다.
int ordinal = today.ordinal(); // 2

// 3. values(): Enum에 정의된 모든 상수를 배열로 반환한다.
Day[] days = Day.values();
for (Day d : days) {
    System.out.println(d);
}

// 4. valueOf(String name): 주어진 문자열과 일치하는 Enum 상수를 반환한다.
Day day = Day.valueOf("MONDAY");

주의: ordinal()은 상수의 선언 순서에 의존하므로 상수의 순서가 바뀌면 예기치 않은 버그가 발생할 수 있다. 실무에서는 ordinal()에 의존하는 로직을 작성하지 않는 것이 바람직하다.


5. Enum에 필드와 메서드 추가하기

Java의 Enum은 단순한 상수의 집합을 넘어 일반 클래스처럼 필드, 생성자, 메서드를 가질 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public enum PayType {
    CARD("신용카드", 0.0),
    ACCOUNT_TRANSFER("계좌이체", 0.005),
    MOBILE("휴대폰 결제", 0.02);

    // 필드 선언 (불변성을 위해 final 권장)
    private final String description;
    private final double feeRate;

    // 생성자 (Enum 생성자는 기본적으로 private)
    PayType(String description, double feeRate) {
        this.description = description;
        this.feeRate = feeRate;
    }

    // Getter 메서드
    public String getDescription() {
        return description;
    }

    // 수수료 계산 로직 추가
    public double calculateFee(int amount) {
        return amount * feeRate;
    }
}

1
2
3
4
5
6
7
8
9
public class PayTest {
    public static void main(String[] args) {
        PayType pay = PayType.MOBILE;

        System.out.println("결제 수단: " + pay.getDescription()); // 휴대폰 결제
        System.out.println("수수료: " + pay.calculateFee(10000)); // 200.0
    }
}


6. 정리

  1. Enum은 연관된 상수들을 안전하고 깔끔하게 관리하기 위해 사용한다.
  2. 컴파일 타임에 타입 체크가 이루어지므로 잘못된 값이 들어오는 상황을 완벽히 방지한다.
  3. 데이터와 관련된 연산 로직을 Enum 내부에 상태와 행위(필드와 메서드)로 묶어서 관리할 수 있으므로 코드의 객체지향적 설계와 가독성이 향상된다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.