본문 바로가기
  • soobinhand의 기술 블로그
도서/자바 프로그래밍 언어 - James Gosling

[자바 프로그래밍 언어] 6장 열거 타입

by soobinhand 2021. 12. 26.
728x90

6.1     단순한 Enum 예제

  • 카드 한 벌을 표시하는 enum은 아래와 같이 선언.
public enum Suit {
    CLUBS,
    DIAMONDS,
    HEARTS,
    SPADES
}
  • 기본적인 형태의 enum은 열거 타입을 표시하는 식별자 enum과 몸체로 구성되며 몸체에는 값이나 enum 상수를 지정할 수 있다. enum 상수는 항상 대문자. enum 상수는 클래스의 정적 필드이다.
  • enum의 인스턴스를 new 연산자로 생성할 수는 없다. 즉, enum에는 접근할 수 있는 생성자가 없다고 봐야 한다. 단지 우리는 enum 상수를 위해 생성된 객체를 사용할 수 있을 뿐이다.
  • 이런 단순한 사용으로 정수형 상수를 선언하는 것과 다른 점을 찾기 어렵겠지만, enum에는 완벽한 타입 안전이라는 중요한 다른 점이 있다.
  • 위의 Suit 타입의 참조에는 Suit에서 정의한 상수와 null을 제외하고는 다른 값을 대입할 수가 없다.

6.2     Enum 선언

  • enum은 클래스와는 다른 두 가지 특징을 가지고 있다. enum 키워드를 class 키워드 대신 사용하며, enum의 클래스 멤버를 선언하기 전에 모든 enum 상수를 먼저 선언해야 한다.
public enum Suit {
    CLUBS,
    DIAMONDS,
    HEARTS,
    SPADES;
    
    public static int getSize(){
        return 4;
    }
}
  • enum타입은 다른 타입을 확장할 수 없다. 왜냐하면 모든 enum이 묵시적으로 java.lang.Enum을 확장하고 있기 때문이다. 다른 어떤 타입도 enum을 확장할 수 없다. 그 이유는 모든 enum타입이 마치 final인 것처럼 동작하기 때문이다. enum은 인터페이스를 한 개 이상 구현할 수는 있다.
  • enum에는 모든 클래스 멤버를 선언할 수 있다. 다시 말해 필드, 메소드, 중첩 타입, 중첨 enum을 선언할 수 있다.
  • enum 상수 그 자체는 묵시적으로 enum과 동일한 타입을 가진 정적 필드이다.
  • 중첩 enum선언은 모든 접근 제한자를 가질 수 있다. 하지만 최상위 enum클래스는 오직 이 클래스가 선언된 패키지 내에서만 접근할 수 있도록 public이거나 생략된 상태여야 한다.
  • 중첩 enum은 오직 정적 멤버만 가질 수 있기 때문에 묵시적으로 static이다. 협약에 따라 static은 항상 생략.
  • enum은 abstract 선언 불가능. 왜냐하면 enum은 확장할 수 없기에 구현하지 않은 메소드를 하위 클래스에 제공할 수 없다.

6.3     Enum 상수 선언

  • 이름으로만 구성된 enum 상수는 묵시적이든 명시적이든 인자가 없는 생성자로 생성할 수 있는 enum 타입의 객체를 생성한다. enum에는 다른 클래스처럼 임의의 생성자를 선언할 수 있다.
enum Suit {
    CLUBS("CLUBS"),
    DIAMONDS("DIAMONDS"),
    HEARTS("HEARTS"),
    SPADES("SPADES");

    String name;
    Suit(String name){
        this.name = name;
    }

    @Override
    public String toString() {
        return "Suit{" +
                "name='" + name + '\'' +
                '}';
    }

    public static void main(String[] args) {
        System.out.println(Suit.CLUBS);
    }
}
  • 각각의 Suit은 String을 인자로 받는 생성자가 설정하는 name 필드를 가진다. 그리고 각각의 enum 상수에는 생성자에 전달할 이름이 선언되어 있다.
  • enum 생성자는 다음과 같은 제약사항을 가진다.
    • 모든 enum 생성자는 private이다. 생성자에 private 접근 제한자를 선언할 수 있지만 협약에 따라 이 제한자는 생략된다. private 생성자는 enum 타입을 직접 인스턴스로 만들 수 없게한다.
    • 생성자는 명시적으로 슈퍼 클래스의 생성자를 호출할 수 없다. 슈퍼 생성자 호출은 컴파일러가 알아서 처리해준다.
    • enum 생성자에는 static필드 이외의 상수는 선언할 수 없다.

6.4     java.lang.Enum

  • 모든 enum 타입은 묵시적으로 java.lang.Enum 을 확장한다. 하지만 어떤 클래스도 Enum을 직접 확장할 수 없다.
  • Enum 에는 다음과 같은 메소드도 있다.
    • public final int ordinal() - enum 상수의 순서 값을 반환.
    • public final Class<E> getDeclaringClass() - enum 상수의 enum 타입을 표현하는 Class 객체 반환

6.5     enum 사용 여부

  • enum으로 정의하고자 하는 타입이 더 정교해질수록 이 타입을 enum으로 표현하는 것이 적당한지에 대해서 더 많이 고려해야 한다.
  • 만약 서브 클래스화하는 것으로 특수화할 필요가 없다면 자신만의 클래스를 생성하는 것보다는 enum 타입을 생성하는 것이 더 나은 방법이다.
728x90

댓글