Java의 정석 의 책을 읽고 정리한 내용입니다.
- 열거형 : 서로 관련된 상수를 편리하게 선언하기 위한 것으로 여러 상수를 정의할 때 사용하면 유용하다.
- 자바의 열거형은
타입에 안전한 열거형
이라서 실제 값이 같아도 타입이 다르면 컴파일 에러가 발생한다.- 열거형은 값뿐만 아니라 타입까지 체크하기 때문에 타입에 안전하다고 하는 것이다.
- 열거형 상수를 사용하면, 기존의 소스를 다시 컴파일하지 않아도 된다.
enum 열거형 이름 { 상수명1, 상수명2, ... }
열거형이름.상수명
==
를 사용할 수 있다.<
, >'
와 같은 비교 연산자는 사용할 수 없고 compareTo()
는 사용할 수 있다.if (idr == Direction,EAST {
x++;
} else if (dir > Direction.WEST) { // 에러 열거형 상수에 비교연산자는 사용 불가능
...
} else if (dir.compareTo(Direction.WEST) > 0) // compareTo()는 가능
...
}
compareTo()
는 두 비교대상이 같으면 0, 왼쪽이 크면 양수, 오른쪽이 크면 음수를 반환한다.
✔️ 모든 열거형의 조상 - java.lang.Enum
Direction[] dArr = Direction.values();
for(Direction d : dArr) // for(Direction d : Direction.values())
System.out.printf("%s=%d%n", d.name(), d.ordinal());
Direction
에 정의된 모든 상수를 출력한다.values()
는 열거형의 모든 상수를 배열에 담아서 반환한다.
메서드 | 설명 |
---|---|
Class<E>getDeclaringClass() | 열거형의 Class객체를 반환한다. |
String name() | 열거형 상수의 이름을 문자열로 반환한다. |
int ordinal() | 열거형 상수가 정의된 순서를 반환한다.(0부터 시작) |
T valueOf(Class<T>enumType, String name) | 지정된 열거형에서 name과 일치하는 열거형 상수를 반환한다. |
valueOf
는 열거형 상수의 이름으로 문자열 상수에 대한 참조를 얻을 수 있게 해준다.
Direction d = Direction.valueOf("WESET");
System.out.println(d); // WEST
System.out.println(Direction.WEST == Direction.valueOf("WEST"); // true
enum Direction { EAST, SOUTH, WEST, NORTH }
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));
// 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.");
break;
}
Direction[] dArr = Direction.values();
for(Direction d : dArr) // for(Direction d : Direction.values())
System.out.printf("%s=%d%n", d.name(), d.ordinal());
}
}
d1=EAST
d2=WEST
d3=EAST
d1==d2 ? false
d1==d3 ? true
d1.equals(d3) ? true
d1.compareTo(d3) ? 0
d1.compareTo(d2) ? -2
The direction is EAST.
EAST=0
SOUTH=1
WEST=2
NORTH=3
&nbps;
&nbps;
enum Direction { EAST(1), SOUSTH(5), WEST(-1), NORTH(10) }
()
와 함게 적어주면 된다.
enum Direction {
EAST(1), SOUSTH(5), WEST(-1), NORTH(10); // 끝에 ';'를 추가해야 한다.
private final int value; // 정수를 저장할 필드(인스턴스 변수)를 추가
Direction(int value) { thi.value=value; } // 생성자를 추가
public int getValue() { return value; }
}
;
도 잊지 말아야 한다.final
이어야 한다는 제약은 없지만, value
는 열거형 상수의 값을 저장하기 위한 것이므로 final
을 붙였다.getValue()
도 추가했다.
Direction d = new Direction(1); // 에러 열거형의 생성자는 외부에서 호출불가
Direction
에 새로운 생성자가 추가되었지만, 열거형의 객체를 생성할 수 없다.private
이기 때문이다.enum Direction {
...
Direction(int value) { // private Direction(int value)와 동일하다
...
}
✔️ 열거형에 추상 메서드 추가하기
enum TRansportation {
BUS(100), TRAIN(150), SHIP(100), AIRPLANE(300);
private final int BASIC_FARE;
private TRansportation(int basicFare) {
BASEIC_FARE = basicFare;
}
int fare() { // 운송 요금을 반환한다
return BASIC_FARE;
}
}
fare(int distance)
를 선언하면 각 열거형 상수가 이 추상 메서드를 반드시 구현해야 한다.enum TRansportation {
BUS(100) {
int fare(int distance) { return distance*BASIC_FARE;}
},
TRAIN(15) { int fare(int distance) { return distance*BASIC_FARE;}},
SHIP(100) { int fare(int distance) { return distance*BASIC_FARE;}},
AIRPLANE(300) { int fare(int distance) { return distance*BASIC_FARE;}},
abstract int fare(int distance); // 거리에 따른 요금을 계산하는 추상 메서드
protected final int BASIC_FARE; // protected로 해야 각 상수에서 접근 가능
Transportation(int basicFare) {
BASIC_FARE = basicFare;
}
public int getBasicFare() { return BASIC_FARE; }
}
열거형 Direction
이 정의되어 있을 때
enum Direction { EAST, SOUTH, WEST, NORTH }
Direction
객체다.
abstract class MyEnum<T extends MyEnum<T>> implements Comparable<T>{
static int id = 0;
int oridinal;
String name = "";
public int oridinal(){ return oridinal; }
MyEnum(String name){
this.name = name;
oridinal = id++;
}
public int compareTo(T t){
return oridinal - t.oridinal();
}
}
abstract class MyTransportation extends MyEnum {
static final MyTransportation BUS = new MyTransportation("BUS", 100) {
int fare(int distance) { return distance - BASIC_FARE; }
};
static final MyTransportation TRAIN = new MyTransportation("TRAIN", 150) {
int fare(int distance) { return distance - BASIC_FARE; }
};
static final MyTransportation SHIP = new MyTransportation("SHIP", 100) {
int fare(int distance) { return distance - BASIC_FARE; }
};
static final MyTransportation AIRPLANE = new MyTransportation("AIRPLANE", 300) {
int fare(int distance) { return distance - BASIC_FARE; }
};
abstract int fare(int distance); // 거리에 따른 요금을 계산하는 추상 메서드
protected final int BASIC_FARE; // protected로 해야 각 상수에서 접근 가능
private MyTransportation(String name, int basicFare){
super(name);
BASIC_FARE = basicFare;
}
public String name() { return name; }
public String toString() { return name; }
}
public class EnumEx4 {
public static void main(String[] args) {
MyTransportation t1 = MyTransportation.BUS;
MyTransportation t2 = MyTransportation.BUS;
MyTransportation t3 = MyTransportation.SHIP;
MyTransportation t4 = MyTransportation.AIRPLANE;
MyTransportation t5 = MyTransportation.AIRPLANE;
System.out.printf("t1=%s, %d%n", t1.name(), t1.oridinal());
System.out.printf("t2=%s, %d%n", t2.name(), t2.oridinal());
System.out.printf("t3=%s, %d%n", t3.name(), t3.oridinal());
System.out.printf("t4=%s, %d%n", t4.name(), t4.oridinal());
System.out.printf("t5=%s, %d%n", t5.name(), t5.oridinal());
System.out.println("t1==t2 ? "+ (t1==t2));
System.out.println("t1.compareTo(t3)="+ t1.compareTo(t3));
}
}
t1=BUS, 0
t2=BUS, 0
t3=TRAIN, 1
t4=SHIP, 2
t5=AIRPLANE, 3
t1==t2 ? true
t1.compareTo(t3)=-1