JAVA의 정석
2018-12-16
열거형(enums)
열거형이란
class Card {
enum Kind { CLOVER, HEART, DIAMOND, SPACE }
enum Value { ONE, TOW, THREE, FOUR }
final Kind kind;
final Value value;
}
자바의 열거형은 C언어의 열거형보다 더 향상된 것으로, 타입까지 관리하기 떄문에 보다 논리적인 오류를 줄일 수 있다.
그리고 더 중요한 것은 상수의 값이 바뀌면, 해당 상수를 참조하는 모든 소스를 다시 컴파일해야 한다는 것이다. 하지만 열거형 상수를 사용하면, 기존의 소스를 다시 컴파일 하지 않아도 된다.
열거형 상수간의 비교에는 '=='를 사용할 수 있다. 그만큼 빠른 성능을 제공한다. 단 비교연산자는 사용 불가하다.
compartTo()는 사용 가능하다.
메서드 | 설명 |
---|---|
Class |
열거형의 Class 객체를 반환한다. |
String name() | 열거형 상수의 이름을 문자열로 반환한다. |
int ordinal() | 열거형 상수가 정의된 순서를 반환한다.(0부터 시작) |
T valueOf(Class |
지정된 열거형에서 name과 일치하는 열거형 상수를 반환한다. |
열거형에 멤버 추가하기
Enum클래스에 정의된 ordinal()이 열거형 상수가 정의도니 순서를 반환하지만, 이 값을 열거형 상수의 값으로 사용하지 않는 것이 좋다. 이 값은 내부적인 용도로만 사용되기 때문이다. 열거형 상수의 값이 불연속적인 경우에는 열거형 상수의 이름 옆에 원하는 값을 괄호()와 함께 적어주면 된다.
enum Direction { EAST(1), SOUTH(5), WEST(-1), NORTH(10) }
지정된 값을 저장할 수 있는 인스턴스 변수와 새엇ㅇ자를 새로 추가해줘야 하는데, 이 때 먼저 열거형 상수를 모두 정의한 다음에 다른 멤버들을 추가해야한다.
enum Direction {
EAST(1), SOUTH(5), WEST(-1), NORTH(10);
private final int value;
Direction(int value) { this.value = value; }
public int getValue() { return value; }
}
필요한 경우 여러 값을 지정할 수 있다.
enum Direction {
EAST(1, ">"), SOUTH(5, "<""), WEST(-1, "^");
private final int value;
Direction(int value) { this.value = value; }
public int getValue() { return value; }
}
열거형의 생성자는 묵시적으로 private이므로 외부에서 생성 불가능하다.
열거형에 추상 메서드 추가하기
열거형에 정의된 추상 메서드를 추가하여 구현할 수 있다.
enum Transportation {
BUS(100) {
int fare(int distance) { return distance * BASIC_FARE; }
}
abstarct int fare(int distance);
protected final int BASEC_FARE;
Transportation(int basicFare) {
BASIC_FARE = basicFare;
}
public int getBasicFare() { return BASIC_FARE; }
}
열거형의 이해
열거형이 내부적으로 구현된 형태를 보여준다.
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;
}
}
Direction클래스의 static상수 EAST, 등드의 값은 객체의 주소이고, 이 값은 바뀌지 안흔 값이므로 '=='로 비교가 가능한 것이다.
abstract class MyEnum<T extends MyEnum<T>> implements Comparable<T> {
static int id = 0;
int ordinal;
String name = "";
public int ordinal() { return ordinal; }
MyEnum(String name) {
this.name = name;
ordinal = id++;
}
public int compareTo(T t) {
return ordinal - t.ordinal();
}
}
만일 클래스를 MyEnum<T>와 같이 선언하였따면, compareTo()를 위와 같이 간단히 작성할 수 없었을 것이다. 타입 T에 ordinal()이 정이되어 있는지 확인할 수 없기 때문이다. 이것은 MyEnum<T>의 자손이어야 한다는 의미로 확실히 알려주기 위해 ordinal을 가지고 있는 MyEnum<T>를 상속 받는다고 정의해 둔 것이다.
'JAVA' 카테고리의 다른 글
[JAVA] Reflection 을 이용하여 Method 호출하기 (0) | 2020.01.08 |
---|---|
[Java] POJO 와 Beans 의 차이점 (0) | 2019.08.24 |
JAVA의 정석 - Thread (0) | 2019.01.13 |
JAVA의 정석 - Generics (0) | 2019.01.13 |