2020-03-08-TIL

Java enum

enum이란?

enum은 enumeration이라는 셈,계산, 열거, 목록이라는 영어단어의 앞부분만 따서 만든 예약어입니다. 어떤 클래스가 상수만으로 작성되어 있으면 반드시 class로 선언할 필요는 없다. 이럴 땐 class로 선언된 부분에 enum이라고 선언하면 이 객체는 상수의 집합이라는 것을 명시적으로 나타냅니다.

enum을 사용한 상수 정의하기

enum은 열거형이라고 한다. 열거형은 서로 연관된 상수들의 집합이라고 할 수 있다.

enum에 대한 예제는 다음과 같다.

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

enum Month{  
    JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, 
    AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER;
}

public class EnumExample {

    public static void main(String[] args) {        

        Day day = Day.MONDAY;

        switch (day) {
        case MONDAY:
            System.out.println("월요일입니다.");
            break;
        case TUESDAY:
            System.out.println("화요일입니다.");
            break;
        case WEDNESDAY:
            System.out.println("수요일입니다.");
            break;

            /*
             * ... 생략 ...
             */
        }
    }
}

enum이 나오기 전에는 class 또는 interface를 사용하여 정의하였습니다. 하지만 이제는 enum 키워드를 사용하면 됩니다. 위 예제처럼 enum이라는 키워드를 사용하고 상수의 집합을 의미하는 이름을 입력하면 됩니다. 그리고 위 예제처럼 각각의 상수들의 이름을 차례대로 나열하면 상수가 정의됩니다.

enum 사용시의 장점

  • 코드가 단순해지며 가독성이 좋다.
  • 인스턴스 생성과 상속을 방지한다.
  • 키워드 enum을 사용하기 때문에 구현의 의도가 열거임을 분명하게 나타낼 수 있다.

enum과 생성자

1. enum 클래스의 원소에 추가 속성 부여

enum의 각 열거형 상수에 추가 속성을 부여할 수 있습니다. 예를 들어, enum타입의 상수들이 행성(Planet)을 의미할 때, 이름을 나타내는 상수뿐 만이 아니라 질량과 반지름이라는 속성까지 함께 표현할 수 습니다. 다음의 예제는 왼쪽과 오른쪽을 나타내는 상수에 한글이름이라는 추가 속성을 부여합니다.

public enum RoadSide {  
    //
    Left("왼쪽"),
    Right("오른쪽"); 

    private String krName;

    private RoadSide() {
        //
    } 

    private RoadSide(String krName) {
        this.krName = krName; 
    }

    public String getKrName() {
        return krName; 
    }
}

생성자의 파라미터를 통해 추가 속성을 enum클래스의 필드(field)에 설정해주고, getter 메소드를 통해 해당 속성을 필요할 때에 가져다 쓸 수 있게 합니다. 이러한 기능들을 사용하면 enum은 열거형 상수를 모아 놓은 간단한 형태에서 시작하지만, 끊임없이 진화하여 완벽한 추상체가 될 수 있는 것이다.

2. enum 생성자는 private이어야 한다.

enum 타입은 고정된 상수들의 집합으로써, 런타임(Run-time)이 아닌 컴파일타임(Compile-Time)에 모든 값을 알고 있어야 합니다. 즉 다른 패키지나 클래스에서 enum 타입에 접근해서 동적으로 어떤 값을 정해줄 수 없습니다. -> 컴파일 시에 타입 안정성이 보장된다. 이러한 이유 때문에 생성자의 접근제어자를 private로 설정해야 합니다.

enum 활용

if문 사용 줄이기

스위치를 on/off 하는 예제에서 on이면 전원을 off하고, off이면 전원을 on하는 예제를 사용해보겠다.

public enum PowerSwitch {  
    //
    ON("켜짐"),
    OFF("꺼짐");

    private String krName;

    private PowerSwitch(){
        //
    }

    private PowerSwitch(String krName){
        this.krName = krName;
    }

    public String getKrName(){
        return krName;
    }

    public PowerSwitch opposite() {
        // 
        if (this == PowerSwitch.ON) {
            return PowerSwitch.OFF;  
        } else {
            return PowerSwitch.ON; 
        }
    }
}

opposite() 메소드를 활용해서 if/else문을 줄일 수 있습니다.

로또의 랭크와 갯수를 한번에 저장하고 싶다면 객체를 만들면 되는거 아닌가?