IT_Programming/Java

[JAVA] 열거타입 enum

JJun ™ 2013. 12. 4. 10:38



 출처: http://hyeonstorage.tistory.com/174





열거타입 enum


Java에서 열거 타입 enum을 정의할 수 있으며, 변수를 선언할 때 변수 타입으로 사용할 수 있다.

enum은 그 타입 변수의 모든 가능한 값을 열거함으로써 지정할 수 있다.


enum Season {winter, spring, summer, fall}


enum에서 나열할 수 있는 값들의 수는 제한이 없다.


Season time;


변수 time 은 가질 수 있는 값이 제한되어 Season의 4개 값 중 하나만 가질 수 있다.
그 외의 값을 가지게 되면 컴파일 오류가 발생한다.


time = Season.spring;


enum은 변수가 가질 수 있는 값의 수가 적을 때 꽤 도움이 된다.
예를 들어 학생이 받을 수 있는 학점을 나타낸다고 가정하면 다음과 같이 enum을 선언할 수 있다.


enum Grade {A, B, C, D, F}


Grade는 이 학점중의 하나의 값만 가질 수 있다.



* enum의 메쏘드


 Static Methods

valueOf(String arg) 

 String 값을 enum에서 가져온다. 값이 없으면 Exception 발생

valueOf(Class<T> class, String arg)

 넘겨받은 class에서 String을 찾아, enum에서 가져온다.
 valueOf(String arg)는 내부적으로 자기 자신의 class를 가져오는 것이다.

values()

 enum의 요소들을 순서대로 enum 타입의 배열로 리턴한다.

 ENUM$VALUES의 카피이므로, 너무 자주 호출하는 것은 좋지 않음.

Static 아닌 Methods 

name() 

 호출된 값의 이름을 String으로 리턴한다. 

ordinal()

 해당 값이 enum에 정의된 순서를 리턴한다 

compareTo(E o)

 이 enum과 지정된 객체의 순서를 비교한다.
 지정된 객체보다 작은 경우 음의 정수, 동일하면 0, 크면 양의 정수를
 반환한다.

equals(Object other) 

 지정된 객체가 이 enum 정수와 같은 경우, true를 반환한다. 



* enum 활용 예제


 

public class enumTest {

    
    // City 열거형 객체 선언
    public enum City { Seoul, Busan, Daegu, Gwangju, Daejun }
    
    // Season 열겨형 객체 선언
    public enum Season{
        
        spring("March through May"),
        summer("June through August"),
        fall("September through November"),
        winter("December through February");
    
        private String span;
        
        // 열거 값에 (String) 값 span 에 대입
        Season(String months){
            span = months;
        }
        
        // span 값 반환
        public String getSpan(){
            return span;
        }
    }
    
    
    public static void main(String[] args){
        
        // City enum에서 "Seoul" 가져옴.
        City city1 = City.valueOf("Seoul");
        
        // name(), ordinal() 호출   < Seoul, 0 >
        System.out.println("city1 : " + city1.name());
        System.out.println("city1's order : " + city1.ordinal());
        System.out.println();
        
        
        // City enum에서 "Daegu" 가져옴.   City.valueof("Daegu")와 동일
        City city2 = City.Daegu;
        
        // name(), ordinal() 호출  < Deagu, 2 >
        System.out.println("city2 : " + city2.name());
        System.out.println("city2's order : " + city2.ordinal());
        System.out.println();
        
        
        // Seson.values()로 데이터를 배열로 가져온다.
        // 배열 순서대로 time 값과 time.getspan()을 호출한다.
        for(Season time : Season.values()){
            System.out.println(time + " " + time.getSpan());
        }
    }
}



* 실행 결과




- enum City


위의 예제에서 City와 Season 두가지 enum 열거형 데이터를 선언했다.

기본적으로 City와 같은 enum을 많이 사용한다. 이렇게 제한된 값만을 처리할 때 enum을 처리 한다.
만약 City에 없는 Jeonju 와 같은 값을 호출하게 되면 java.lang.IllegalArgumentException이 발생하게 된다.



- enum Season


enum Season과 같이 기본적인 열거형 데이터 외에도, 연관된 데이터를 같이 선언할 수 있고, enum안에 함수도 선언할 수 있다. 

각 데이터에 연관된 값을 가져오려면 위의 예제와 같이 함수를 선언하여 값을 처리 하고, get 함수를 선언해야 enum에서 가져올 수 있다.

이 방법도 잘 활용하면 유용하게 사용할 수 있다.



- enum은 한정된 데이터를 다루므로 조건문을 사용시 Switch 문을 사용하면 유용하게 사용할 수 있다.



* 암묵적으로 정의되는 메쏘드


enum City {Seoul, Busan, Daegu, Gwangju, Daejun}


이것은 아래와 같이 Compile이 된다. 참고하자


 final class City extends Enum<City> {

private City(String name, int ordinal) { super(name, ordinal); } public static final Status Seoul = new Status("Seoul", 0); public static final Status Busan = new Status("Busan", 1); public static final Status Deagu = new Status("Daegu", 2);

public static final Status Gwangju = new Status("Gwangju", 3); public static final Status Daejun = new Status("Daejun", 4);

private static final Status ENUM$VALUES[] = { Seoul, Busan, Daegu, Gwangju, Daejun }; }



* enum의 특이사항


enum은 생성자가 private 이므로 new로 새로운 인스턴스를 만들 수 없다.

newInstance() 에 의해 인스턴스를 만들 수 없다. newInstance()를 호출 하면 InstantiationException이 발생한다.

clone()을 만들 수 없다.
Enum 클래스를 상속받고 있지만, clone() 메쏘드가 final로 지정되어 있어 사용하면 CloneNotSupportedException이 발생한다.

Serialize : enum의 값이 수정되어 순서가 변경되어도, ordinal 값이 다시 재 정의 된다.