일정 개수의 상수 값을 정의한 다음, 그 외의 값은 허용하지 않는 타입을 열거 타입이라고한다. 이런 상수들을 int
나 String
으로 열거하게 된다면 단점이 있다.
- 타입 안전을 보장할 방법이 없고 표현력이 떨어진다. 즉 전혀 관계 없는 타입들의 연산을 하더라도 컴파일러는 경고를 하지않는다.
예시:
public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;
public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOOD = 2;
int i = (APPLE_FUJI - ORANGE_TEMPLE) / APPLE_PIPPIN;
-
namespace를 지원하지 않기 때문에 접두사를 쓰면서 이름이 길어진다.
-
정수 열거의 경우 출력하게 되면 숫자로만 보여서 도움이되지 않고, 문자열의 경우는 문자열 값을 하드코딩할 수도 있게되며, 이 때 오타가 발생해도 찾기가 쉽지않다.
enum
을 사용하면 상수 하나당 자신의 인스턴스를 하나씩 만들어 public static final 필드로 공개한다. 따라 서 인스턴스를 딱 하나만 존재하는 것이 보장된다. 그리고 위의 문제들을 모두 해결할 수 있다.
Enum의 장점
- 열거 타입 상수 각각을 특정 데이터와 연결 지을 수 있다. 따라서 연관된 상수들을 묶어서 관리할 수 있다.
예시:
public enum Planet {
MERCURY(3.302e+23, 2.439e6),
VENUS (4.869e+24, 6.052e6),
EARTH (5.975e+24, 6.378e6),
MARS (6.419e+23, 3.393e6),
JUPITER(1.899e+27, 7.149e7),
SATURN (5.685e+26, 6.027e7),
URANUS (8.683e+25, 2.556e7),
NEPTUNE(1.024e+26, 2.477e7);
private final double mass; // 질량(단위: 킬로그램)
private final double radius; // 반지름(단위: 미터)
private final double surfaceGravity; // 표면중력(단위: m / s^2)
// 중력상수(단위: m^3 / kg s^2)
private static final double G = 6.67300E-11;
// 생성자
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
surfaceGravity = G * mass / (radius * radius);
}
public double mass() { return mass; }
public double radius() { return radius; }
public double surfaceGravity() { return surfaceGravity; }
public double surfaceWeight(double mass) {
return mass * surfaceGravity; // F = ma }
}
}
- 상수마다 동작이 달라져야 하는 상황도 처리할 수 있다. 즉, 상태와 행위를 한 곳에 표현할 수 있다.
예시:
public enum Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x / y; }
};
private final String symbol;
Operation(String symbol) { this.symbol = symbol; }
@Override public String toString() { return symbol; }
public abstract double apply(double x, double y);
}
위의 경우에는 Functional Interface를 이용하여서도 구현할 수 있다.
public enum Operation {
PLUS((x, y) -> x + y),
MINUS((x, y) -> x - y),
TIMES((x, y) -> x * y),
DIVIDE((x, y) -> x / y);
private BiFunction<Double, Double, Double> operationFuntion;
}
참고
-
https://jaehun2841.github.io/2019/02/03/effective-java-item34/#잔업-수당-전략-선택하기
-
https://woowabros.github.io/tools/2017/07/10/java-enum-uses.html
-
Effective Java 3rd Edition: Item 34 int 상수 대신 열거 타입을 사용하라
댓글남기기