Stay Hungry Stay Foolish

자바/자바 중급

[자바 중급] 05. 열거형 Enum

dev스카이 2024. 10. 8. 22:12

타입 안전 열거형 패턴 - Enum

enum은 enumeration의 줄임말로 변역하면 열거라는 뜻이고, 어떤 항목을 나열하는 것을 뜻한다. 타입 안전 열거형 패턴을 사용하면 나열한 항목만 사용할 수 있다. 

public class ClassGrade {
 	public static final ClassGrade BASIC = new ClassGrade();
 	public static final ClassGrade GOLD = new ClassGrade();
 	public static final ClassGrade DIAMOND = new ClassGrade();
}

 

위 코드는 타입 안전 열거형 패턴을 직접 구현한 것이다. BASIC, GOLD, DIAMOND라는 상수를 선언했다. static을 사용해서 상수를 메서드 영역에 선언하고, final을 사용해서 인스턴스를 변경할 수 없게 한다. 

 

나열한 항목은 상수로 선언한 BASIC, GOLD, DIAMOND이고 원래는 'String'을 사용해서 선언했겠지만 위에서는 'CLASSGRADE'라는 클래스로 선언했다. 그러므로 이 세 개만 안전하게 사용할 수 있다는 것이다.

 

 

타입 안전 열거형 패턴"(Type-Safe Enum Pattern)의 장점

  • 타입 안정성 향상 : 정해진 객체만 사용할 수 있기 때문에, 잘못된 값을 입력하는 문제를 근본적으로 방지할 수 있다.
  • 데이터 일관성 : 정해진 객체만 사용하므로 데이터의 일관성이 보장된다.
  • 제한된 인스턴스 생성 : 클래스는 사전에 정의된 몇 개의 인스턴스만 생성하고, 외부에서는 이 인스턴스들만 사용할 수 있도록 한다. 이를 통해 미리 정의된 값들만 사용하도록 보장한다.
  • 타입 안전성 : 이 패턴을 사용하면, 잘못된 값이 할당되거나 사용되는 것을 컴파일 시점에 방지할 수 있다.

 

단점

이 패턴을 구현하려면 위 코드와 같이 많은 코드를 작성해야 하고, private 생성자를 추가하는 등 유의해야 하는 부분들도 있다.

 

 

자바의 열거형(Enum-Type) 제공

열거형 패턴의 단점을 보완하고 개발자가 편리하게 사용할 수 있도록 하기 위해서 자바는 열거형을 제공한다. 다음 예제를 보면 자바가 제공하는 열거형을 확인할 수 있다. 

public enum Grade {
    BASIC, GOLD, DIAMOND
}

 

위에서 열거형 패턴을 직접 구현한 것과 같은 코드이고, 보다 훨씬 간결한 코드인 것을 볼 수 있다. 열거형을 정의할 때는 class 대신에 enum을 사용하고 원하는 상수의 이름을 나열하면 된다.

 

 

특징

  • 열거형도 클래스이다.
  • 열거형은 switch 문에 사용할 수 있다.
  • 'enum'은 열거형 내부에서 상수로 지정하는 것 외에 직접 생성이 불가능하다. 생성하면 컴파일 오류 발생
    • enum 클래스 이외의 클래스에서 enum클래스 객체를 생성하는 것이 불가하다는 것
  • 열거형은 java.lang.Enum 클래스를 자동으로 상속 받는다. 
  • 열거형은 인터페이스를 구현할 수 있다.
  • 열거형에 추상 메서드를 선언하고 구현할 수 있다.

 

장점

  • 타입 안정성 향상 : 열거형은 사전에 정의된 상수들로만 구성되므로, 유효하지 않은 값이 입력될 가능성이 없다. 이런 경우 컴파일 오류가 발생한다.
  • 간결성 및 일관성 : 열거형을 사용하면 코드가 더 간결하고 명확해지며, 데이터의 일관성이 보장된다.
  • 확장성 : 새로운 타입을 추가하고 싶을 때, ENUM에 새로운 상수를 추가하기만 하면 된다.

 

열거형의 주요 메서드

  • values() : 모든 ENUM 상수를 포함하는 배열을 반환한다.
  • valueOf(String name) : 주어진 이름과 일치하는 ENUM 상수를 반환한다.
  • name() : ENUM 상수의 이름을 문자열로 반환한다.
  • ordinal() : ENUM 상수의 선언 순서(0부터 시작)를 반환한다. 
    • 그러나 이 메서드는 가급적 사용하지 않는 것이 좋다. 이 값을 사용하다가 중간에 상수를 선언하는 위치가 변경되면 전체 상수의 위치가 모두 변경될 수 있기 때문이다.
  • toString() : ENUM 상수의 이름을 문자열로 반환한다. name() 메서드와 유사하지만, toString() 은 직접 오버라이드 할 수 있다.

 

※ 객체명.name() : ENUM의 상수 이름을 사용할 수 있다.

※ Enum 클래스명.values() : Enum 열거형의 모든 상수를 배열로 구할 수 있다.