열거형(enum)이란?

  • 서로 연관된 상수들의 집합을 정의
  • class와 유사하다, 다만 enum만을 위한 문법적 형식을 가지고 있기 때문에 enum이라는 키워드를 사용
//예시: 아래 두 코드는 사실상 같다.
enum Fruit{
    APPLE, PEACH, BANANA;
}

class Fruit{
    public static final Fruit APPLE  = new Fruit();
    public static final Fruit PEACH  = new Fruit();
    public static final Fruit BANANA = new Fruit();
    
    private Fruit(){}	//생성자의 접근 제어자가 private
}
  • 생성자의 접근 제어자가 private이므로 인스턴스를 생성할 수 없다

주요 특징

  1. 타입 안전성(Type Safety): Enum은 Java에서 자체 타입을 가집니다. 이는 해당 Enum의 인스턴스가 미리 정의된 값 중 하나임을 보장합니다. 예를 들어, DAYS_OF_WEEK Enum이 있다면 이는 오직 일주일의 일곱 날만을 값으로 가질 수 있습니다.
  2. 객체 지향적 특성: Java의 Enum은 클래스처럼 동작합니다. 즉, 인스턴스 변수와 메서드를 가질 수 있으며, 생성자도 정의할 수 있습니다. 이를 통해 각 Enum 상수에 특정 동작을 부여할 수 있습니다.
  3. 값의 열거: Enum에서는 values() 메서드를 사용하여 모든 Enum 상수들의 배열을 얻을 수 있습니다. 이는 반복문과 결합하여 모든 Enum 상수를 순회하는 데 유용합니다.
  4. switch 문 지원: Enum은 switch 문에서 사용될 수 있습니다. 이를 통해 특정 Enum 값에 대한 다양한 경우를 쉽게 처리할 수 있습니다.
  5. 단일 인스턴스 보장: Enum의 각 상수는 전역적으로 단일 인스턴스를 가집니다. 즉, == 연산자를 사용하여 두 Enum 상수를 안전하게 비교할 수 있습니다.
  6. 직렬화 및 동기화 지원: Enum은 기본적으로 직렬화가 가능하며, 추가적인 동기화나 직렬화 관리가 필요하지 않습니다.

예시

enum Fruit{
    APPLE, PEACH, BANANA;
}
enum Company{
    GOOGLE, APPLE, ORACLE;
}
public class EnumExp {
    public static void main(String[] args) {
        /* 
        // 컴파일 오류 발생
        if(Fruit.APPLE == Company.APPLE){
            System.out.println("과일 애플과 회사 애플이 같다.");
        }
        */
        Fruit type = Fruit.APPLE;
        switch(type){
            case APPLE:
                System.out.println(57+" kcal");
                break;
            case PEACH:
                System.out.println(34+" kcal");
                break;
            case BANANA:
                System.out.println(93+" kcal");
                break;
        }
    }
}
//실행 결과 => 57 kcal
  • enum은 서로 다른 상수 그룹에 대한 비교를 컴파일 시점에서 차단한다
// 컴파일 오류 발생
if(Fruit.APPLE == Company.APPLE){
    System.out.println("과일 애플과 회사 애플이 같다.");
}
  • enum 생성자를 가질 수 있다. 단, 접근제어자는 private만 사용할 수 있다.
enum Fruit{
    APPLE, PEACH, BANANA;
    
    Fruit(){
        System.out.println("Call Constructor "+this);
    }
    
    //컴파일 오류
    /*
    public Fruit(){
        System.out.println("Call Constructor "+this);
    }
    */
}

/* 실행 결과
Call Constructor APPLE
Call Constructor PEACH
Call Constructor BANANA
57 kcal
*/
  • 생성자의 매개변수를 통해서 필드(APPLE..)의 인스턴스 변수 값 부여하기
enum Fruit{
    APPLE("red"), PEACH("pink"), BANANA("yellow");
    public String color;
    Fruit(String color){
        System.out.println("Call Constructor "+this);
        this.color = color;
    }
}
public class EnumExp {
	public static void main(String[] args) {
        Fruit type = Fruit.APPLE;
        switch(type){
        case APPLE:
            System.out.println(57+" kcal, "+Fruit.APPLE.color);
            break;
        case PEACH:
            System.out.println(34+" kcal"+Fruit.PEACH.color);
            break;
        case BANANA:
            System.out.println(93+" kcal"+Fruit.BANANA.color);
            break;
        }
	}  
}
/*결과
Call Constructor APPLE
Call Constructor PEACH
Call Constructor BANANA
57 kcal, red
*/
  • 메소드를 가질 수 있다
public enum Fruit {
    APPLE("red"), PEACH("pink"), BANANA("yellow");
	
	public String color;
    
	Fruit(String color){
        System.out.println("Call Constructor "+this);
        this.color = color;
    }
	
	//메소드
    String getColor(){
        return this.color;
    }	    
}
public class EnumExp {
	public static void main(String[] args) {
        Fruit type = Fruit.APPLE;
        switch(type){
        case APPLE:
            System.out.println(57 + " kcal, " + Fruit.APPLE.getColor());	//getColor 메소드 사용
            break;
        case PEACH:
            System.out.println(34 + " kcal" + Fruit.PEACH.getColor());
            break;
        case BANANA:
            System.out.println(93 + " kcal" + Fruit.BANANA.getColor());
            break;
        }     
	}
}

정리

  • enum은 연관된 값들을 저장하며, 해당 값이 변경되지 않도록 한다
  • 열거형 자체가 클래스이기 때문에 열거형 내부에 생성자, 필드, 메소드를 가질 수 있다

참고

보완/복습

  • 2023.11.23 보완

Git