CodeGym /행동 /JAVA 25 SELF /열거형: enum

열거형: enum

JAVA 25 SELF
레벨 10 , 레슨 4
사용 가능

1. 소개

프로그래밍에서는 미리 정해진 제한된 선택지의 목록을 다루는 일이 많습니다. 예: 요일, 신호등 색, 게임 난이도, 주문 상태. 이런 선택지는 보통 고정된 값으로 표현됩니다. 바로 여기서 오늘의 주제인 열거형(enum)과 맞닿습니다.

열거형은 이름이 붙은 상수 집합을 선언할 수 있게 해 주는 특별한 데이터 타입입니다.

enum은 칸칸이 분류된 상자에 라벨을 붙여 둔 것과 같습니다. 각 라벨은 어떤 숫자에 연결된 고유한 이름입니다.

enum의 주요 장점:

  • 코드가 더 읽기 쉽고 자체 문서화됩니다;
  • 0, 1, 2 같은 "매직 넘버" 대신 DayOfWeek.MONDAYTrafficLight.RED처럼 의미 있는 이름을 사용합니다;
  • 잘못된 값을 대입하려 하면 컴파일러가 오류를 알려 줍니다;
  • 각 요소 뒤에는 사실… 평범한 정수가 있습니다! (이 부분은 뒤에서 다시 다룹니다.)

enum 선언 문법


// 열거형 선언의 일반 템플릿
public enum Imya
{
    KONSTANTA1 ,
    KONSTANTA2 ,
    KONSTANTA3
}
enum 열거형 선언 문법

Java에서 열거형을 선언하는 것은 매우 쉽습니다. 기본 예시는 다음과 같습니다:

// 파일 DayOfWeek.java
public enum DayOfWeek {
    MONDAY,			// 0	
    TUESDAY,		// 1
    WEDNESDAY,		// 2
    THURSDAY,		// 3
    FRIDAY,			// 4
    SATURDAY,		// 5
    SUNDAY			// 6
}

설명:

  • 키워드 enum은 컴파일러에게 "이건 열거형이다!"라고 알려 줍니다.
  • 중괄호 안에는 쉼표로 구분된 값 이름(상수)들이 옵니다.
  • 이름은 보통 UPPER_SNAKE_CASE(모두 대문자, 단어 사이에 밑줄)로 작성합니다.

enum은 어디에 선언할 수 있을까요?

  • 별도의 파일(DayOfWeek.java)에서.
  • 클래스 내부(해당 클래스만을 위한 private 열거형이 필요할 때).
  • 메서드 내부에서도 가능하지만, 자주 쓰이진 않습니다.

2. 코드에서 enum 사용

enum 변수 선언:

DayOfWeek today = DayOfWeek.MONDAY;

이제 today에는 DayOfWeek에 선언된 값들만 대입할 수 있습니다.

switch에서의 사용 예

switch (today) 
{
    case MONDAY:
        System.out.println("아, 월요일...");
        break;
    case FRIDAY:
        System.out.println("야호, 금요일!");
        break;
    default:
        System.out.println("평범한 날.");
}

중요한 차이점: case에서는 변수의 타입을 컴파일러가 이미 알고 있다면 접두사 없이 상수 이름만 적습니다.

모든 enum 값 순회

모든 enum에는 values()라는 정적 메서드가 있어, 모든 값을 담은 배열을 반환합니다:

for (DayOfWeek day : DayOfWeek.values()) 
{
    System.out.println(day);
}

메뉴 표시, 검증, 후보 생성 등에 아주 유용합니다.

3. enum 메서드: name(), ordinal(), valueOf()

Java의 열거형은 단순한 상수 목록이 아니라 메서드를 가진 온전한 클래스입니다!

name() 메서드

코드에 작성된 그대로의 상수 이름을 문자열로 반환합니다:

DayOfWeek day = DayOfWeek.FRIDAY;
System.out.println(day.name()); // "FRIDAY"

ordinal() 메서드

상수의 순번(0부터 시작)을 반환합니다:

System.out.println(DayOfWeek.MONDAY.ordinal()); // 0
System.out.println(DayOfWeek.FRIDAY.ordinal()); // 4

주의: 나중에 순서가 바뀔 수 있다면 ordinal() 값으로 저장하거나 비교하지 마세요! 이름을 사용하는 것이 좋습니다.

valueOf(String name) 메서드

문자열을 해당 enum 값으로 변환합니다(해당 상수가 존재할 경우):

DayOfWeek day = DayOfWeek.valueOf("MONDAY");
System.out.println(day); // MONDAY

일치하는 상수가 없으면 IllegalArgumentException이 발생합니다.

values() 메서드

모든 enum 값의 배열을 반환합니다(위에서 이미 예시를 보았습니다):

DayOfWeek[] days = DayOfWeek.values();

4. 필드, 생성자, 메서드를 가진 enum

Java의 열거형은 확장할 수 있습니다: 필드, 생성자, 메서드를 추가할 수 있어요! 단순한 이름 목록이 아니라 작은 클래스라고 생각하면 됩니다.

예: 현지화된 요일 이름

public enum DayOfWeek 
{
    MONDAY("Ponedel’nik"),
    TUESDAY("Vtornik"),
    WEDNESDAY("Sreda"),
    THURSDAY("Chetverg"),
    FRIDAY("Pyatnitsa"),
    SATURDAY("Subbota"),
    SUNDAY("Voskresen’e");

    private final String russianName;

    // 생성자(기본적으로 private)
    DayOfWeek(String russianName) 
    {
        this.russianName = russianName;
    }

    public String getRussianName() 
    {
        return russianName;
    }
}

이게 어떻게 동작하는지는 27레벨 이후 OOP를 배울 때 더 자세히 알아봅니다 :P

이제 이렇게 사용할 수 있습니다:

DayOfWeek day = DayOfWeek.WEDNESDAY;
System.out.println(day.getRussianName()); // "Sreda"

포인트: 각 enum 값은 자신의 데이터를 가질 수 있습니다(이 경우 — 러시아어 이름).

enum 사용의 장점

  • 타입 안전성: 열거형에 없는 값을 실수로 대입할 수 없습니다.
  • 가독성: 코드가 스스로를 설명합니다(TrafficLight.RED vs 1 또는 "red").
  • 유지보수 용이성: 항목을 추가/삭제해야 할 때 한 곳만 수정하면 됩니다.
  • switch와 잘 작동: enum은 값에 따라 분기하는 데 최적입니다.
  • 확장 가능: 필드와 메서드를 추가하고 인터페이스도 구현할 수 있습니다.
  • 오류 감소: 컴파일러가 경우를 빠뜨리지 않도록 도와줍니다(특히 switch 구문에서).

6. 실습: 우리 애플리케이션에 enum 사용하기

우리의 미니 애플리케이션에 enum을 이용한 요일 지원을 추가해 봅시다.

1단계. enum 선언

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

2단계. 코드에서 사용

System.out.println("요일을 입력하세요(예: MONDAY):"); 
Scanner console = new Scanner(System.in);                      
String input = console.nextLine().toUpperCase();               
                                                               
DayOfWeek day = DayOfWeek.valueOf(input);                      
switch (day) 
{                                                 
    case MONDAY:                                               
        System.out.println("업무 주의 시작!");          
        break;                                                 
    case FRIDAY:                                               
        System.out.println("곧 주말!");                 
        break;                                                 
    case SATURDAY:                                             
    case SUNDAY:                                               
        System.out.println("와, 주말이다!");                  
        break;                                                 
    default:                                                   
        System.out.println("평범한 근무일.");           
}                                                              

동작 설명:

  • 사용자가 요일을 입력합니다(예: "monday" 또는 "MONDAY").
  • 대소문자에 영향을 받지 않도록 문자열을 대문자로 변환합니다(toUpperCase()).
  • valueOf로 문자열을 enum 값으로 변환합니다.
  • switch로 서로 다른 메시지를 출력합니다.
  • 잘못된 입력이면 예외를 잡아 경고를 출력합니다.

7. enum 사용 시 흔한 실수

오류 №1: enum 대신 문자열이나 숫자를 사용함. 초보자는 종종 이렇게 작성합니다:

int day = 1; // 1이 월요일인가요?

또는

String status = "DELIVERED";

좋지 않습니다: 철자가 틀릴 수 있고 유지보수가 어렵습니다. enum을 사용하세요!

오류 №2: ==.equals()로 enum 비교. Java에서는 enum 값을 ==로 비교해도 안전합니다. 각 값이 해당 enum 클래스 내에서 유일하기 때문입니다:

if (day == DayOfWeek.MONDAY) { ... } // OK!

.equals()도 동작하지만, 보통은 ==를 더 자주 사용합니다.

오류 №3: 열거형 항목의 나쁜 이름. 요소 이름을 VALUE1, VALUE2, VALUE3처럼 짓지 마세요 — 한 달 뒤엔 아무도 그 의미를 모릅니다! 의미 있는 이름을 사용하세요.

오류 №4: 로직에 ordinal()을 사용함. 이렇게 작성하지 마세요:

if (day.ordinal() == 0) { ... } // 그러지 마세요!

요소 순서는 바뀔 수 있으며, 그러면 모든 것이 망가집니다. 이름을 사용하세요!

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION