JDK1.5부터 열거형이 추가되었는데 이는 값뿐만 아니라 타입까지 체크하기 때문에 타입에 안전하다.
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}
열거형 상수에 값을 저장하기 위해서는 인스턴스 변수와 생성자를 새로 추가해야 한다.
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];
}
}