Java 자바 Enum 열거형 사용법

Enum이란?

Enum은 “enumeration”의 줄임말로, 특정 값들의 집합을 정의할 수 있는 특별한 클래스입니다. 예를 들어, 요일, 방향, 상태와 같이 정해진 값들만 사용해야 하는 경우에 사용됩니다. Enum은 이 값을 상수처럼 관리할 수 있게 해주며, 코드의 안전성과 가독성을 높이는 데 큰 도움을 줍니다.

Enum의 기본 구조

자바에서 Enum을 선언하는 방법은 다음과 같습니다.

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

위의 코드에서 Day라는 Enum은 7개의 요일을 상수로 가지고 있습니다. 각 상수는 Enum 타입의 객체로 취급됩니다.

Enum의 기본 특성

  • 불변성(Immutability): Enum의 각 상수는 불변 객체입니다.
  • 타입 안전성(Type Safety): Enum을 사용하면 잘못된 값이 사용되는 것을 컴파일 시점에 방지할 수 있습니다.
  • 싱글턴 패턴: 각 상수는 사실상 싱글턴 객체입니다. 따라서 Enum 값은 메모리 내에서 하나의 인스턴스만 가지게 됩니다.

Enum의 사용법

Enum 상수를 사용하는 방법은 다음과 같습니다.

Java
Day today = Day.MONDAY;

if (today == Day.MONDAY) {
    System.out.println("It's Monday!");
}
Java

위 코드에서 today는 Day 타입의 Enum이며, Day.MONDAY 값을 가지고 있습니다.

Enum의 메서드

Enum은 기본적으로 Object 클래스의 메서드 외에도 몇 가지 유용한 메서드를 제공합니다.

  • name(): Enum 상수의 이름을 문자열로 반환합니다.
  • ordinal(): Enum 상수가 선언된 순서를 반환합니다(0부터 시작).
  • values(): Enum의 모든 상수를 배열로 반환합니다.
  • valueOf(String name): 전달된 문자열이 Enum 상수의 이름과 일치하는 경우, 해당 Enum 상수를 반환합니다.
  • compareTo(): Enum 상수 간의 순서를 비교합니다.
Java
Day today = Day.FRIDAY;

System.out.println(today.name()); // "FRIDAY"
System.out.println(today.ordinal()); // 4

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

Day dayFromString = Day.valueOf("MONDAY");
System.out.println(dayFromString); // "MONDAY"

int comparison = today.compareTo(Day.MONDAY);
System.out.println(comparison); // 4 (FRIDAY는 MONDAY보다 뒤에 있음)
Java

Enum과 switch 문

Enum은 switch 문과 함께 사용하기에 매우 유용합니다. 예를 들어, 요일에 따라 다른 메시지를 출력하는 코드를 작성할 수 있습니다.

Java
Day today = Day.WEDNESDAY;

switch (today) {
    case MONDAY:
        System.out.println("Start of the work week.");
        break;
    case WEDNESDAY:
        System.out.println("Midweek.");
        break;
    case FRIDAY:
        System.out.println("Almost weekend!");
        break;
    default:
        System.out.println("Weekend!");
        break;
}
Java

Enum에 멤버 변수와 메서드 추가하기

Enum은 단순한 상수 집합 이상의 기능을 가질 수 있습니다. 멤버 변수와 메서드를 추가하여 각 상수에 더 많은 의미를 부여할 수 있습니다.

Java
public enum Planet {
    MERCURY(3.303e+23, 2.4397e6),
    VENUS(4.869e+24, 6.0518e6),
    EARTH(5.976e+24, 6.37814e6);

    private final double mass;   // in kilograms
    private final double radius; // in meters

    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    public double getMass() {
        return mass;
    }

    public double getRadius() {
        return radius;
    }

    public double surfaceGravity() {
        final double G = 6.67300E-11;
        return G * mass / (radius * radius);
    }
}
Java

위 코드에서 Planet Enum은 행성의 질량과 반지름을 멤버 변수로 가지고 있으며, 이를 기반으로 표면 중력(surfaceGravity)을 계산하는 메서드를 제공합니다.

Enum과 추상 메서드

Enum 상수마다 서로 다른 동작을 구현해야 하는 경우가 있습니다. 이때 추상 메서드를 Enum에 선언하고 각 상수에서 이를 구현할 수 있습니다.

Java
public enum Operation {
    PLUS {
        double apply(double x, double y) { return x + y; }
    },
    MINUS {
        double apply(double x, double y) { return x - y; }
    },
    TIMES {
        double apply(double x, double y) { return x * y; }
    },
    DIVIDE {
        double apply(double x, double y) { return x / y; }
    };

    abstract double apply(double x, double y);
}
Java

이렇게 구현하면 각 Enum 상수는 자신만의 메서드를 가질 수 있습니다.

Enum과 인터페이스

Enum이 인터페이스를 구현하도록 할 수도 있습니다. 이는 Enum에 공통된 동작을 부여하면서도 각 상수에 따라 다르게 동작하도록 할 수 있는 방법입니다.

Java
interface Printable {
    void print();
}

public enum Color implements Printable {
    RED {
        public void print() {
            System.out.println("Color is Red");
        }
    },
    GREEN {
        public void print() {
            System.out.println("Color is Green");
        }
    },
    BLUE {
        public void print() {
            System.out.println("Color is Blue");
        }
    }
}
Java

위 코드에서 Color Enum은 Printable 인터페이스를 구현하며, 각 상수는 print 메서드를 다르게 구현합니다.

Enum을 사용하는 이유

1. 코드의 가독성 향상

Enum은 코드의 가독성을 크게 향상시킵니다. 예를 들어, 상태를 나타내는 여러 상수를 사용할 때, 단순한 문자열이나 숫자를 사용하는 것보다 Enum을 사용하는 것이 의도와 의미를 명확하게 전달할 수 있습니다.

2. 타입 안전성 제공

Enum을 사용하면 컴파일 시점에 잘못된 값이 사용되는 것을 방지할 수 있습니다. 이는 코드의 안정성을 크게 높여줍니다.

3. 유지보수성 향상

새로운 값이 필요할 때 Enum에 쉽게 추가할 수 있습니다. 이는 유지보수성을 높이는 데 큰 도움을 줍니다.

Enum 사용 시 주의 사항

1. Enum 상수 간의 순서

ordinal() 메서드는 상수의 선언 순서를 반환합니다. 그러나 이 순서에 의존하는 코드는 권장되지 않습니다. Enum 상수의 순서는 변경될 수 있으므로, 이 순서에 의존하는 코드는 의도치 않은 버그를 초래할 수 있습니다.

2. EnumSet과 EnumMap의 사용

자바 컬렉션 프레임워크는 Enum을 위한 EnumSet과 EnumMap을 제공합니다. 이는 Enum 타입을 사용하는데 최적화된 컬렉션입니다. EnumSet은 Enum 상수의 집합을 효율적으로 관리하고, EnumMap은 Enum 상수를 키로 사용하는 맵입니다.

Java
EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);
EnumMap<Day, String> dayDescriptions = new EnumMap<>(Day.class);
dayDescriptions.put(Day.MONDAY, "Start of the week");
Java

3. 역직렬화 시 Enum의 보장된 싱글턴

Enum은 자동으로 Serializable 인터페이스를 구현하며, 역직렬화된 Enum 상수는 항상 동일한 인스턴스를 유지합니다. 이는 자바가 Enum의 싱글턴 특성을 보장하기 위해 특별한 처리를 해주기 때문입니다.

결론

자바의 Enum은 유연한 기능을 제공하는 도구로, 코드의 가독성, 안전성, 유지보수성을 크게 향상시킬 수 있습니다. Enum을 사용함으로써 특정 값들의 집합을 명확하고 안전하게 정의할 수 있으며, 다양한 메서드와 기능을 통해 다양한 상황에서 효율적으로 활용할 수 있습니다. 또한, Enum에 멤버 변수와 메서드를 추가하거나, 추상 메서드 및 인터페이스를 구현함으로써 더욱 확장된 기능을 제공할 수 있습니다.

Leave a Comment