열거형 enum

정순동·2023년 12월 31일
0

자바기초

목록 보기
69/89

여러 상수를 선언해야 할 떄, 편리하게 선언할 수 있는 방법을 열거형(enum)이라고 한다.

	class Card {
    	static final int CLOVER = 0;
        static final int HEART = 1;
        static final int DIAMOND = 2;
        static final int SPADE = 3;
        
        static final int TWO = 0;
        static final int THREE = 1;
        static final int FOUR = 2;
        
        final int kind;
        final int num;
    }

위 처럼 많은 상수를 아래처럼 enum을 사용하면 자동으로 0,1,2,3... 식으로 값까지 부여해 준다.

	class Card {
    	enum Kind { CLOVER, HEART, DIAMOND, SPADE } // 열거형 Kind를 정의
        enum Value { TWO, THREE, FOUR } // 열거형 Value를 정의
    	
        final Kind kind;	// 타입이 Kind임
        final Value value;
    }

참고로 C에서는 열거형의 값만을 비교하지만 JAVA에서는 해당 열거형의 타입까지 비교하기에 좀 더 안전한 코드를 작성가능하다.

	// C
    if(Card.Kind.CLOVER == Card.Value.TWO) // 0 == 0으로 true
    // JAVA
    if(Card.Kind.CLOVER == Card.Value.TWO) // 타입 불일치로 인해 컴파일 에러

열거형의 정의

열거형을 정의하는 방법은 아래와같다. 그저 괄호 안에 상수의 이름을 나열하기만 하면 된다.

	enum 열거형이름 { 상수명1, 상수명2, ... }

동서남북을 상수로 정의한다면 아래와같다.

	enum Direction { EAST, SOUTH, WEST, NORTH }

열거형의 참조

이 열거형에 정의된 상수를 사용하려면 '열거형이름.상수명'처럼 사용한다.

	class Unit {
    	int x, y;	// 유닛의 위치
        Direction dir;	// 열거형 인스턴스 변수를 선언
        
        void init() {
        	dir = Direction.EAST; // 유닛의 방향을 EAST로 초기화
        }
    }

열거형의 비교

열거형 상수간의 비교에는 '=='를 사용할 수 있다. 그만큼 eqauls()보다 빠른 성능을 제공하지만 '<', '>'와 같은 비교연산자를 사용할 수 없지만 compareTo()는 사용가능하다.

※열거형 상수는 하나하나가 객체이기 때문에 <,>가 사용 불가능하다.

	if(dir == Direction.EAST) {
    	x++;
    } else if (dir > Direction.WEST) { // 에러. 비교연산자x
    	...
    } else if (dir.compareTo(Direction.WEST) > 0) { // compareTo()가능
    	...
    }

열거형의 조상 - java.lang.Enum

모든 열거형의 조상은 java.lang.Enum이며 아래와 같은 메서드를 제공한다.

이 외에도 컴파일러가 아래 메서드들을 자동으로 추가한다.

	static E[] values()
    static E valueOf(String name)

예제

enum Direction { EAST, SOUTH, WEST, NORTH };
public class EnumExample {
    public static void main(String[] args) {
        Direction d1 = Direction.EAST;
        Direction d2 = Direction.valueOf("WEST");
        Direction d3 = Enum.valueOf(Direction.class, "EAST");

        System.out.println("d1 = " + d1);
        System.out.println("d2 = " + d2);
        System.out.println("d3 = " + d3);

        System.out.println("d1 == d2 ? " + (d1 == d2));
        System.out.println("d1 == d3 ? " + (d1 == d3));
        System.out.println("d1.equals(d3) ? " + d1.equals(d3));
//        System.out.println("d2 > d3 ? " + (d1 > d3)); // 에러
        System.out.println("d1.compareTo(d3) ? " + (d1.compareTo(d3)));
        System.out.println("d1.compareTo(d2) ? " + (d1.compareTo(d2)));

        switch(d1) {
            case EAST: // Direction.EAST라고 쓸 수 없다.
                System.out.println("The Direction is EAST");
                break;
            case SOUTH:
                System.out.println("The Direction is SOUTH");
                break;
            case WEST:
                System.out.println("The Direction is WEST");
                break;
            case NORTH:
                System.out.println("The Direction is NORTH");
                break;
            default:
                System.out.println("Invalid direction.");
        }

        Direction[] dArr = Direction.values();

        for(Direction d : dArr) // for(Direction d : Direction.values())
            System.out.printf("%s=%d%n", d.name(), d.ordinal());
    }
}

위 예제에서 d.ordinal()로 Direction열거형안의 상수들의 순서를 빼왔다. 따로 상수들에게 값을 주지 않았다면 값 = 위치값 으로 oridnal()만 사용해서 값을 빼 올수 있지만 상수들에게 따로 값을 준 경우라면 순서와 상수의값이 일치하지 않는다.

열거형에 멤버 추가하기

열거형 상수의 값이 불규칙적인 경우에는 다음과 같이 열거형 상수의 이름 옆에 원하는 값을 괄호()와 함께 적어준다.

	enum Direction { EAST(1), SOUTH(5), WEST(-1), NORTH(10) }

이와 함께 저장할 수 있는 인스턴스 변수와 생성자를 추가하는데 이 때 주의해야 할 점은 먼저 열거형 상수를 모두 정의한 다음에 다른 멤버들을 추가해야 한다는 것이다.

enum Direction2 {
        EAST(12), SOUTH(24), WEST(31), NORTH(46);

        private final int value;    // 정수를 저장할 필드(인스턴스 변수)를 추가
        
        Direction2(int value) {
            this.value = value;
        }
        
        public int getValue() { return value; }
    }

열거형의 인스턴스 변수는 반드시 final이어야 한다는 제약은 없지만, value는 열거형 상수의 값을 저장하기 위한 것이므로 final을 붙였다.

	Direction2 d = new Direction2(1); //에러. 열거형의 생성자는 외부에서 호출할 수 없다.

열거형의 생성자는 제어자가 private이기 때문에 외부에서 호출불가하다.

0개의 댓글