enum class 총정리

홍성덕·2025년 1월 19일

enum 클래스란?

미리 정의된 상수들로 이루어진 제한된 집합을 표현하기 위한 클래스

enum 클래스 사용 이유

  1. 의미 있는 이름을 가진 상수들을 하나의 그룹으로 관리함으로써 코드의 가독성이 높아진다.
  2. enum 클래스에 어떤 상수가 있는지 컴파일러가 미리 알고 있기 때문에 자바에서 switch-case문을 사용할 때 default 절을 생략 가능하다. 코틀린에서는 when 문을 사용할 때 else문을 생략 가능하다.
  3. 타입 안정성 : 타입 안정성(Type Safety)은 프로그래밍에서 예상된 데이터 타입만을 사용하도록 보장하여, 잘못된 타입의 데이터가 사용되는 것을 방지하는 특성
public static final int JANUARY = 31;

public void printDays(int days) {
    System.out.println("Days: " + days);
}

// 메소드 호출
printDays(JANUARY); // 정상 동작
printDays(30);      // 논리적으로 잘못된 값이 전달될 수 있음

예를 들어, 1월이 31일까지인데 static final int JANUARY = 31로 선언을 하고, 이 값을 사용하려는 메소드의 파라미터가 int 타입이면, JANUARY를 전달하든, 그냥 31이라는 숫자를 전달하든 메소드는 잘 동작할 것이다. 꼭 31이 아니어도 다른 숫자도 전달할 수 있는데, 그러면 일단 동작은 하겠지만 의도치 않은 결과가 나올 것이다. 이것은 안전하지 않은 방법이다.

public enum Month {
    JANUARY(31),
    FEBRUARY(28),
    MARCH(31),
    // ... 다른 월들
    ;

    private final int days;

    Month(int days) {
        this.days = days;
    }

    public int getDays() {
        return days;
    }
}

public void printDays(Month month) {
    System.out.println("Days in " + month.name() + ": " + month.getDays());
}

// 메소드 호출
printDays(Month.JANUARY); // 정상 동작
// printDays(31);         // 컴파일 에러 발생

하지만 Month라는 enum 클래스를 정의하고 JANUARY(31) 이런 enum 상수를 선언한 다음, 메소드의 파라미터를 Month 타입으로 선언하면 오로지 해당 enum 상수만 인자로 전달 가능하므로 잘못된 인자 전달을 미리 방지할 수 있다.

enum 클래스 특징

  • enum 상수는 enum 클래스가 JVM에 의해 로드되고 초기화될 때 객체로 생성된다.
  • 클래스 로딩 시점은 enum 클래스가 처음 참조될 때(예를 들어 enum 상수에 접근할 때) 발생하며, 이때 모든 상수가 싱글 인스턴스(단일 인스턴스)로 생성된다.
  • enum 상수는 불변이며, 애플리케이션 전체에서 하나의 객체만 존재한다.
  • enum 클래스는 생성자가 private으로 제한되어 있어 외부에서 새로 생성할 수 없다. 접근제어자를 사용하지 않고 생성자를 선언하면 기본적으로 private이다. public이나 protected를 생성자에 사용해서는 안 된다. 즉, 각 상수를 enum 클래스 내에서 선언할 때에만 생성자를 사용할 수 있고 외부에서는 사용할 수 없다.
  • enum 클래스의 생성자를 직접 선언하지 않으면, 일반 클래스와 마찬가지로 컴파일할 때 매개 변수가 없는 기본 생성자를 자동으로 만들어준다. 그래서 직접적인 생성자 선언 없이도 상수를 선언할 수 있는 것이다.

enum 클래스의 생성자가 private인 이유

enum 클래스는 외부에서 객체를 생성하지 못하게 하기 위해서 생성자를 private으로 선언해야 한다. enum은 고정된 상수들의 집합으로 컴파일 타임에 이미 모든 값에 대해 컴파일러가 알고 있다. 그런데 런타임 중간에 다른 객체를 생성한다면 코틀린의 when문이나 자바의 switch-case문에서 예상치 못한 동작을 할 수 있다. (갑자기 else문으로 처리해야 할 일이 생겨버린다.)

profile
안드로이드 주니어 개발자

0개의 댓글