티스토리 뷰

JAVA/정리

java enum 열거형

란텔 2014. 1. 22. 20:10

열거형이란 의미상 관련이 있는 상수값들의 집합을 의미한다.


어떤 클래스에 상수로 정의된 변수가 있다고 했을 때, 그 상수의 변경으로 인해서 상수를 참조하는 다른 특정 클래스들도 모두 컴파일을 해야 적용이 되었는데, 상수 대신 열거형을 사용하면 컴파일 하지 않아도 된다.


열거형을 정의 하는 방법은 간단하다.

enum 열거형이름 { 열거형상수명1, 열거형상수명2, ....... } enum Military { ARMY, NAVY, AIRFORCE }


열거형의 상수에 접근하는 방법은 간단하다. 마치 클래스의 static멤버의 접근방법과 같은 방법을 취한다.

열거형이름.상수명

Military.ARMY




모든 열거형은 java.lang.Enum클래스를 조상으로 한다.

이 Enum클래스에는 몇가지 메서드가 정의되어 있다.

리턴타입

메서드
final intcompareTo(E o)
비교연산자 대신에 쓰이며(열거형에서는 >, < 연산 사용 불가) 
두 열거형의 크기를 비교할 때 사용
왼쪽 열거형이 크면 양수, 같으면 양수, 오른쪽 열거형이 크면 음수를 반환



final Class<E>

getDeclaringClass()
열거형의 클래스 객체를 반환



final String

 name()
해당 열거형 상수의 이름을 문자열로 반환


final intordinal()
내부적으로 정의된 상수의 순서를 반환한다(0부터 시작한다.)


중요하다고 생각되는 메서드만 적었지만 보시다시피 전부 다 final메서드이다. 알고 있겠지만 final이 붙은 메서드는 오버라이딩을 할 수가 없다. 그러므로 위 메서드 사용시에는 Enum의 규칙을 따라야한다.


또 컴파일러가 자동적으로 추가해주는 메서드가 있는데..

static E values() : 열거형의 모든 상수를 타입[] 형식으로 리턴한다.

static E valueOf(String name) : name에 대한 열거형 참조를 가져온다.





아래 코드는 Enum의 메서드들을 테스트 해본 것이다.

package 이넘; public class EnumEx2 { enum DollarLate { //1달러당 환율 1200원 110엔 7위안 1파운드 KR(1200), JP(110), CN(7), UK(1); private final int value; private DollarLate(int value){ this.value=value; } public int getValue(){ return value; } /*public String toString(){ return "ads"; }*/ } public static void main(String[] args){ DollarLate[] dlArr = DollarLate.values(); //열거형의 상수 목록을 배열로 가져온다. for(DollarLate dl : dlArr){ System.out.print(dl.name()+", "); //name()으로 상수이름을 가져온다. System.out.print(dl.getValue()+", "); System.out.print(dl.ordinal()+", "); //내부적으로 정의된 상수가 정의된 순서값 반환 System.out.print(dl.getDeclaringClass()); //해당 enum의 참조를 가져온다. System.out.println(); } DollarLate dl = DollarLate.valueOf("UK"); //EnumType.valueof(String name) name과 일치하는 열거형 참조를 가져온다. System.out.println(dl); System.out.println((DollarLate.KR).compareTo(DollarLate.JP)); //ordinal을 비교대상으로 한다. } }

------------결과-------------------------------------

KR, 1200, 0, class 이넘.EnumEx2$DollarLate

JP, 110, 1, class 이넘.EnumEx2$DollarLate

CN, 7, 2, class 이넘.EnumEx2$DollarLate

UK, 1, 3, class 이넘.EnumEx2$DollarLate

UK

-1

------------------------------------------------------


DollarLate은 환율을 1달러당 각나라의 화폐단위로 표현한 enum타입 열거형이다.

이 코드에서는 열거형을 기본적으로 정의하지 않고, 열거형 상수의 값을 상수의 이름 옆에 ()를 이용해 직접 할당해 줬는데....

이런식으로 코딩하기 위해서는 

private final T 변수

private 생성자

public T get변수

를 정의 해줘야한다.


또 눈여겨 보아야 할 점은 compareTo()메서드이다. enum 열거형은 '=='등가비교연산자를 이용해 서로 같은 상수인지 판단이 가능하지만 '>', '<'와 같은 크기 비교연산자는 사용할 수 없다. 그 대신에 compareTo()메서드를 제공하는데 다음과 같이 Enum클래스를 까보면..

public final int More ...compareTo(E o) {
        Enum other = (Enum)o;
        Enum self = this;
        if (self.getClass() != other.getClass() && // optimization
            self.getDeclaringClass() != other.getDeclaringClass())
            throw new ClassCastException();
        return self.ordinal - other.ordinal;
    }

이 메서드는 좌측 객체와 우측 객체를 비교해서 좌측이 크면 양수, 같으면 0, 우측이 크면 음수를 리턴한다. 보면 알겠지만 비교대상이 되는게 ordinal이라는 변수이다. 이 변수는 직접 정의한 enum 열거형 타입 객체와 상관없이 내부적으로 0부터 시작하는 정수를 각각의 상수가 그 값을 가진다. 그래서 위 코드에서 보는 것처럼 (DollarLate.KR).compareTo(DollarLate.JP)  가 1200-110이기 때문에 양수가 나와야 하지만 ordinal비교인 0-1이 되기 때문에 음수인 -1이 출력되었다.


이런 문제를 해결하기 위해 여러가지 방법을 사용 하겠지만 본인은 Comparator인터페이스를 enum 열거형 타입인 DollarLate에 구현해주었다.

 //enum 열거형 내부에 넣어줄 코드

@Override public int compare(Object o1, Object o2) { DollarLate d1 = (DollarLate)o1; DollarLate d2 = (DollarLate)o2; int i1 = d1.getValue(); int i2 = d2.getValue(); if(i1 > i2){ return 1; }else if(i1 < i2){ return -1; } return 0; } //main메서드에 넣어줄 코드 System.out.println(dl.compare(DollarLate.KR, DollarLate.JP));

이런식으로 코딩하면 원하는 결과를 얻을 수 있을 것이다.






열거형은 각 상수들은 사실 열거형 타입 객체와 1:1 대응된다.

enum SmartPhone { SAMSUNG, LG, APPLE }

SmartPhone s1 = SmartPhone.LG

SmartPhone s2 = SmartPhone.APPLE

처럼 말이다.


만약에 위와 같은 타입의 열거형이 있다고 할 때 이를 클래스로 표현하면 다음과 같은 형태를 가질 것이다.

class SmartPhone { static final SmartPhone samsung = new SmartPhone("SAMSUNG"); static final SmartPhone lg = new SmartPhone("LG"); static final SmartPhone apple = new SmartPhone("APPLE"); private String name; private SmartPhone(String name){ this.name=name; } }


'JAVA > 정리' 카테고리의 다른 글

자바7  (0) 2014.11.26
[코딩]List안에 Map자료구조의 데이터 정렬  (0) 2014.06.08
HashSet, TreeSet  (0) 2014.01.21
[Collection Framework] ArrayList, LinkedList  (0) 2014.01.16
Exception 예외처리  (0) 2013.12.30
Comments
최근에 올라온 글
최근에 달린 댓글
TAG
more
Total
Today
Yesterday