자바의 열거형에 대해 학습하세요.
자바에서 열거형 지원하기 전에는?
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER; = 2;
public static final int SEASON_FALL = 3;
public static final int SEASON_WINTER = 4;
public static final int BACKEND_FRAMEWORK_SPRING = 1;
public static final int BACKEND_FRAMEWORK_DJANGO = 2;
public static final int BACKEND_FRAMEWORK_EXPRESS = 3;
public static final int BACKEND_FRAMEWORK_LARAVE = 4;
int
이므로 타입 안전성 X (위의 경우 두 SPRING
이 모두 int 1이기 때문에 ==
비교시 true
반환)SPRING
의 의미가 여럿일 경우 변수명에 직접 이름 구분 필요enum
은 이러한 문제점을 해결하고, 여러 장점을 가져오는데...enum 열거형명 { 상수명1, 상수명2 ...}
enum BackendFramework { SPRING, DJANGO, EXPRESS, LARAVE }
enum Season { SPRING, SUMMER, FALL, WINTER;
Season(){ // private 생성자만 가능
System.out.println(this + " init");
}
}
public class Enum {
public static void main(String[] args) {
System.out.println("=====before=====");
System.out.println(Season.SPRING);
System.out.println("=====after=====");
System.out.println();
Season season1 = Season.SPRING;
Season season2 = Season.SPRING;
System.out.println("season1 == season2 :" + season1 == season2);
System.out.println();
BackendFramework bf1 = BackendFramework.SPRING;
// System.out.println(season1 == bf1); 컴파일 에러! 타입 안전
}
}
/*
실행결과
=====before=====
SPRING init
SUMMER init
FALL init
WINTER init
SPRING
=====after=====
season1 == season2 :true
*/
public static final
로 하나씩 생성private
만 가능열거 타입 상수 각각을 틍정 데이터와 연결하고 싶다면?
// <이펙티브 자바 3/E> 코드 34-3 데이터와 메서드를 갖는 열거 타입
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
}
}
출저: 이펙티브 자바 3/E
상수별 메서드 구현
switch
문 대신 상수별 메서드 구현 고려enum Enum {
VAL1 {@Override public void info() { ... }},
VAL2 {@Override public void info() { ... }},
VAL3 {@Override public void info() { ... }},
VAL4 {@Override public void info() { ... }};
public abstract void info(...));
}
이외 고려사항 예시
switch
문 고려Enum 활용 예시
java.lang.Enum
은 추상 클래스로, 열거형이 자동으로 상속받는 부모 클래스Enum
은 impelements
는 가능하나 extends
는 불가Comparable<E>, Serializable
구현java.lang.Enum
메서드
Method | Description |
---|---|
clone() | CloneNotSupportedException 예외 던짐 |
compareTo(E o) | 비교 가능한 타입일시 각 ordinal의 차이를 반환 |
getDeclaringClass() | 열거형의 Class 객체 반환 |
name() | 열거형 상수의 이름을 문자열로 반환 |
ordinal() | 열거형 상수의 순서 반환(0부터 시작) |
valueOf(Class<T> enumType, String name) | 지정된 열거형(param1)에서 이름(param2)과 일치하는 열거형 상수 반환 |
ordinal()
을 사용하지 말자, 순서에따라 자동으로 부여하기때문에 유지보수 어렵다values()
와 valueOf(String name)
은 컴파일러가 모든 열거형에 자동으로 추가Method | Description |
---|---|
values() | 열거형의 모든 상수를 배열에 담아 반환 |
valuesOf(String name) | 열거형 상수의 이름으로 문자열 상수에 대한 참조 반환 Planet.valueOf("EARTH") == Planet.EARTH |
EnumSet
을 사용하면 열거형 상수의 값으로 구성된 집합을 간단히 생성할 수 있다Set
인터페이스를 구현한 클래스며 이에 대한 다형성 활용 가능EnumSet.of()
등 메서드 사용생성 예시
import java.util.EnumSet;
enum Planet {
MERCURY,
VENUS,
EARTH,
MARS,
JUPITER,
SATURN,
URANUS,
NEPTUNE;
}
public class EnumSetEx {
public static void main(String[] args) {
EnumSet<Planet> planets = EnumSet.allOf(Planet.class);
EnumSet<Planet> planetsHasRing = EnumSet.of(Planet.JUPITER, Planet.SATURN, Planet.URANUS, Planet.NEPTUNE);
System.out.println("planets : " + planets);
System.out.println("planetsHasRing : " + planetsHasRing);
}
}