본문 바로가기
JAVA

[자바] Enum Class

by 감자b 2024. 12. 24.

Enum이란?

enumeration 의 줄임말로 열거라는 뜻이고, 어떤 항목을 나열하는 것을 의미한다. 즉 일련의 명명된 상수들의 집합을 정의하는 것을 뜻한다.

 

Enum 클래스의 이해를 위해 예시를 하나 들어보도록 하겠다.

다음과 같이 요일별로 할인율을 반환해주는 메서드가 있다고 하자. (간략하게 월, 수, 일만 할인 적용)

public class PayService {
    public int discount(String day) {
        int percent = 0;
        if (day.equals("MONDAY")) {
            percent = 3;
        } else if (day.equals("WEDNESDAY")) {
            percent = 5;
        } else if (day.equals("SUNDAY")) {
            percent = 10;
        } else {
            System.out.println("할인 X");
        }
        return percent;
    }
}
public class PayMain {
    public static void main(String[] args) {
        PayService payService = new PayService();
        int discount = payService.discount("MONDAY");
        System.out.println("할인율 : " + discount + "%");
    }
}

위 코드에서 discount 메서드는 String 타입의 문자열을 파라미터로 받게 되는데

이렇게 되면 이 메서드를 호출하려고 할 때 오타를 내거나, 요일을 잘못 입력하는 경우가 생길 수 있다.

ex.. int discount = payService.discount("MUNDAY");

이는 타입 안정성이 떨어지고 데이터의 일관성 역시 떨어지며 컴파일 시점에 오류를 잡을 수 없다는 문제가 있다.

 

그러면 이를 방지하기 위해선 어떻게 해야할까?

→ 요일 클래스를 따로 만들고 상수화를 한다.

public class Day {
    private static final String MONDAY = "MONDAY";
    private static final String TUESDAY = "TUESDAY";
    private static final String WEDNESDAY = "WEDNESDAY";
    private static final String THURSDAY = "THURSDAY";
    private static final String FRIDAY = "WEDNESDAY";
    private static final String SATURDAY = "SATURDAY";
    private static final String SUNDAY = "SUNDAY";
}
public class PayService {
    public int discount(String day) {
        int percent = 0;
        if (day.equals(Day.MONDAY)) {
            percent = 3;
        } else if (day.equals(Day.WEDNESDAY)) {
            percent = 5;
        } else if (day.equals(Day.SUNDAY)) {
            percent = 10;
        } else {
            System.out.println("할인 X");
        }
        return percent;
    }
}
public class PayMain {
    public static void main(String[] args) {
        PayService payService = new PayService();
        int discount = payService.discount(Day.MONDAY);
        System.out.println("할인율 : " + discount + "%");
    }
}

이렇게 함으로써 코드가 명확해지고 오타를 입력할 가능성도 없어졌지만 여전히 개발자가 Day 클래스에 있는 문자열 상수를 사용하지 않는다면 오류가 생길 수 있다.

 

위의 문제들을 해결하기 위해 enum 타입의 클래스가 생기게 되었다.

자바에서 제공하는 enum을 사용하기 전에 먼저 enum 클래스 동작 방식을 알기 위해 타입 안전 열거형 패턴을 비슷하게 구현을 해보도록 하자.

public class Day {
    private Day() {
    }
    public static final Day MONDAY = new Day();
    public static final Day TUESDAY = new Day();
    public static final Day WEDNESDAY = new Day();
    public static final Day THURSDAY = new Day();
    public static final Day FRIDAY = new Day();
    public static final Day SATURDAY = new Day();
    public static final Day SUNDAY = new Day();
    
}

위 코드처럼 단지 문자열 상수를 정의하는 것이 아니라 상수마다 별도의 인스턴스를 생성한다.

 

이는 static으로 선언되어 메서드 영역에 한 번 올라간 뒤로 계속 남아있게 되며, Day 클래스의 메타데이터로 저장, 메서드 영역에 상수 풀에도 저장이 되고(힙 영역의 참조를 가지고 있음) final이므로 참조값 역시 변경할 수 없게 된다. 또한 private 생성자를 이용해 외부에서 새로운 타입의 생성 역시 방지한다.

public class PayService {
    public int discount(Day day) {
        int percent = 0;
        if (day == Day.MONDAY) {
            percent = 3;
        } else if (day == Day.WEDNESDAY) {
            percent = 5;
        } else if (day == Day.SUNDAY) {
            percent = 10;
        } else {
            System.out.println("할인 X");
        }
        return percent;
    }
}

 

이로써 잘못된 문자열이 파라미터로 들어오는 문제 역시 수정을 할 수 있게 되었다.

 

자바는 위에서 구현한 타입 안전 열거형 패턴을 쉽게 구현할 수 있도록 enum 클래스를 지원한다.

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

다음과 같이 매핑도 가능

public enum Day {
    MONDAY("월요일"),
    TUESDAY("화요일"),
    WEDNESDAY("수요일"),
    THURSDAY("목요일"),
    FRIDAY("금요일"),
    SATURDAY("토요일"),
    SUNDAY("일요일");

    private final String description;

    Day(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}

enum 특징

  • 열거되는 모든 단어들은 상수 → 대문자로 작성
  • 타입 안전성이 보장 (정의된 상수들만 사용 가능)
  • 메서드와 필드를 가질 수 있음 (객체지향적)
  • enum에서 정의한 생성자는 private
  • 인스턴스 생성이 불가능함
  • enum class 타입의 변수는 Reference Type
  • enum class는 java.lang.Enum 클래스를 자동 상속

'JAVA' 카테고리의 다른 글

[자바] Exception  (0) 2024.12.24
[자바] 중첩 클래스  (0) 2024.12.24
[자바] Wrapper 클래스  (0) 2024.12.24
[자바] String  (0) 2024.12.24
[자바] 오버로딩, 오버라이딩  (0) 2024.12.24