자바의 정석 Chapter 12 열거형

Eunkyung·2021년 11월 3일
0

Java

목록 보기
12/21

1. 열거형

JDK1.5부터 열거형이 추가되었는데 이는 값뿐만 아니라 타입까지 체크하기 때문에 타입에 안전하다.

1.2 열거형의 정의와 사용

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

열거형 상수간의 비교에는 '=='와 equals() 둘다 사용 가능하다.
그러나 '<','>'와 같은 비교연산자는 사용할 수 없는데 그 이유는 열거형이 객체이기 때문이다. 따라서 비교하기 위해서는 compareTo() 메소드를 사용해야 하며 해당 메소드는 final로 정의되어 있어 오버라이딩할 수 없다.

좀 더 자세히 열거형의 내부를 살펴보자.
enum Direction {EAST, SOUTH, WEST, NORTH} 사실 이렇게 정의된 열거형의 상수 하나하나가 Direction 객체이다.

class Direction {
    static final Direction EAST = new Direction("EAST");
    static final Direction SOUTH = new Direction("SOUTH");
    static final Direction WEST = new Direction("WEST");
    static final Direction NORTH = new Direction("NORTH");

    private String name;

    private Direction(String name) {
        this.name = name;
    }
}

Diretion클래스의 static 상수 EAST, SOUTH, WEST, NORTH의 값은 객체의 주소이고, 이 값은 바뀌지 않는 값이기 때문에 '=='로 비교 가능하다.
또한 Enum 클래스가 Comparable 인터페이스를 구현하고 있기 때문에 compareTo()로 열거형 상수간의 비교가 가능하다.

전체 소스코드

public class EnumEx1 {
    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));
        // 열거형 상수간의 비교에는 '<','>'와 같은 비교연산자는 사용할 수 없고 compareTo()는 사용가능하다.
        // why? 열거형은 객체이기 때문에 객체 비교 시 compareTo() 사용
//        System.out.println("d2>d3 ? " + (d2 > d3)); 에러
        System.out.println("d1.compareTo(d3) ? " + d1.compareTo(d3));
        System.out.println("d1.compareTo(d2) ? " + d1.compareTo(d2)); // 선언된 순서로 비교

        switch (d1) {
            case EAST: // 열거형 이름은 적지않고 상수의 이름만 적는다.
                System.out.println("EAST");
                break;
            case WEST:
                System.out.println("WEST");
                break;
            case NORTH:
                System.out.println("NORTH");
                break;
            case SOUTH:
                System.out.println("SOUTH");
                break;
            default:
                System.out.println("Invalid");
                break;
        }
        Direction[] darr = Direction.values();
        for (Direction d : darr) {
            // 열거형 상수의 이름과 순서 반환
            System.out.printf("%s=%d%n", d.name(), d.ordinal());
        }

    }
}

enum Direction {EAST, SOUTH, WEST, NORTH}

1.3 열거형에 멤버 추가하기

열거형 상수에 값을 저장하기 위해서는 인스턴스 변수와 생성자를 새로 추가해야 한다.

전체 소스코드

package ch12.EnumEx1.EnumEx2;

public class EnumEx2 {
    public static void main(String[] args) {
        for (Direction d : Direction.values()) {
            System.out.printf("%s=%d%n", d.name(), d.getValue()); // 상수 이름과 값 출력
        }
        Direction d1 = Direction.EAST;
        Direction d2 = Direction.of(2);

        System.out.printf("d1=%s, %d%n", d1.name(), d1.getValue());
        System.out.printf("d2=%s, %d%n", d2.name(), d2.getValue());

        System.out.println(Direction.EAST.rotate(1));
        System.out.println(Direction.EAST.rotate(2));
        System.out.println(Direction.EAST.rotate(-1));
        System.out.println(Direction.EAST.rotate(-2));

    }
}

enum Direction {
    EAST(1, ",>"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");

    public static final Direction[] DIR_ARR = Direction.values();
    // 열거형 상수값을 저장하기 위해 final로 정의
    private final int value; // 정수를 저장할 iv 추가
    private final String symbol;


    // 생성자 추가
    Direction(int value, String symbol) { // 접근제어자 private 생략됨
        this.value = value;
        this.symbol = symbol;
    }

    public int getValue() {
        return value;
    }

    public String getSymbol() {
        return symbol;
    }

    // 방향을 회전시키는 메서드. num의 값만큼 90도씩 시계방향으로 회전한다.
    public static Direction of(int dir) {
        if (dir < 1 || dir > 4) {
            throw new IllegalArgumentException("Invalid value : " + dir);
        }
        return DIR_ARR[dir - 1];
    }

    public Direction rotate(int num) {
        num %= 4;
        if (num < 0) { // num이 음수일 때는 시계반대 방향으로 회전
            num += 4;
        }
        return DIR_ARR[(value - 1 + num) % 4];
    }
}

출력결과

출처

  • 자바의 정석 - 남궁성 지음
profile
꾸준히 하자

0개의 댓글