minseoBae 2024. 3. 13. 11:11

자바의 Enum은 Enumeration의 약자로 JDK 5부터 지원하는 기능이다.

이는 어떤 상수들을 표현하고자 할 때, 만약 요일을 상수로 표현하고자 한다면

public class DayType {
	public final static int SUNDAY = 0;
	public final static int MONDAY = 1;
	public final static int TUESDAY = 2;
					...
}

이런 식으로 final static int로 정의된 상수를 6개 가지고 있다. 여기서 문제는 요일을 나타내는 값이 int형이라는 것이다.

int today = 100;

이렇듯 정해진 값만 변수에 할당 할 수 없다는 문제점이 있다. 이를 타입에 안전하지 않다(No Type-Safety)고 말한다. 이는 컴파일 오류 없이 잘못된 값을 할당할 수 있으며, 런타임 오류를 발생시켜 프로그램 작동에 문제가 생길 수 있다.

 

Enum 사용하기

 

클래스를 생성하는 것과 같은 방식으로 Enum을 생성한다.

com.example.enumtype패키지를 생성한다.

생성된 패키지 아래에 Day enum을 생성한다.

package examples.enumtype;

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

 

이런 식으로 SUNDAY부터 SATURDAY까지 0~6까지의 숫자를 지정할 수 있다. 

 

이를 응용해서 피자의 사이즈 별로 직경과 가격을 가진 PIZZA enum 클래스를 만들어보았다.

public class EnumExam1 {
    public enum PizzaSize {
        SMALL(10, 5000),
        MEDIUM(12, 7000),
        LARGE(14, 9000);

        private final int diameter;
        private final int price;

        private PizzaSize(int diameter, int price) {
            this.diameter = diameter;
            this.price = price;
        }

        public int getDiameter() {
            return diameter;
        }

        public int getPrice() {
            return price;
        }

        @Override
        public String toString() {
            return String.format("%s (직경: %dcm, 가격: ₩%d)", name(), diameter, price);
        }

        public void print(){
            System.out.println("피자의 직경, 가격 : " + diameter + ", " + price);
        }
    }

    public static void main(String[] args) {
        EnumExam1.PizzaSize size = EnumExam1.PizzaSize.MEDIUM;
        System.out.println(size); // MEDIUM (직경: 12cm, 가격: ₩7000)

        System.out.println("직경: " + size.getDiameter() + "cm");
        System.out.println("가격: " + size.getPrice() + "₩");

        size.print();
    }
}

 

위에서 알 수 있는 Enum의 특징들에는

  •  Enum 타입은 생성자를 가질 수 있는데, 단 생성자는 private해야 한다. 때문에 내부에서만 호출가능하다.
  • Enum안에 선언된 메소드나 변수를 가질 수 있다.
  • 또한 Object가 가지고 있는 메소드를 오버라이딩할 수도 있다.
  • size를 출력할 때 size의 toString()메소드가 리턴한 결과가 출력되는 것을 알 수 있다.
  • PizzaSize Enum타입이 가지고있는 print()메소드를 호출했다.

실행 결과

MEDIUM (직경: 12cm, 가격: ₩7000)
직경: 12cm
가격: 7000₩
피자의 직경, 가격 : 12, 7000

 

EnumMap은 Enum 타입을 키(key)로 사용할 수 있도록 도와주는 클래스이다.

public class EnumExam2 {

    public enum PizzaSize {
        SMALL(10, 5000),
        MEDIUM(12, 7000),
        LARGE(14, 9000);

        private final int diameter;
        private final int price;

        private PizzaSize(int diameter, int price) {
            this.diameter = diameter;
            this.price = price;
        }

        public int getDiameter() {
            return diameter;
        }

        public int getPrice() {
            return price;
        }

        @Override
        public String toString() {
            return String.format("%s (직경: %dcm, 가격: ₩%d)", name(), diameter, price);
        }
    }

    public static void main(String[] args) {
        // 피자 주문 정보를 저장할 EnumMap 생성 (키: 피자 종류, 값: 주문 개수)
        EnumMap<PizzaSize, Integer> orderMap = new EnumMap<>(PizzaSize.class);

        // 피자 주문 (MEDIUM 피자 2개, LARGE 피자 1개)
        orderMap.put(PizzaSize.MEDIUM, 2);
        orderMap.put(PizzaSize.LARGE, 1);

        // 주문 정보 출력
        System.out.println("피자 주문내역:");
        for (PizzaSize size : orderMap.keySet()) {
            System.out.printf("%s 피자: %d개\n", size, orderMap.get(size));
        }

        // 총 주문 금액 계산
        int totalPrice = 0;
        for (PizzaSize size : orderMap.keySet()) {
            totalPrice += orderMap.get(size) * size.getPrice();
        }
        System.out.println("총 주문 금액: " + totalPrice + "₩");
    }
}
  • orderMap EnumMap 배열를 생성하는데, Key로 사용할 Enum타입 PizzaSize.class를 생성자 인자로 전달하였다.
  • 키(key)값으로 Enum타입 PizzaSize에서 정의한 상수를 사용하였다. 미디엄 피자 2개와 라지 피자 1개를 주문 배열에 넣었다.

실행결과

피자 주문내역:
MEDIUM (직경: 12cm, 가격: ₩7000) 피자: 2개
LARGE (직경: 14cm, 가격: ₩9000) 피자: 1개
총 주문 금액: 23000₩

EnumSet과 인터페이스, 추상메소드에 대한 개념은 다음에 다뤄보겠다.