열거형 Enum
Enum
열거형이라고 부르며, 서로 연관된 상수들의 집합을 의미한다. 기존에 상수를 정의할때는 final static String과 같은 문자열이나 숫자로 나
타냈었는데, enum을 사용하면 보다 코드의 가독성을 높힐 수 있다.
Enum의 특징
- 열거 타입 자체는 클래스이다.
- 상수 하나당 자신의 인스턴스를 하나씩 만들어 public static final 필드로 공개한다.
- 밖에서 접근할 수 있는 생성자를 제공하지 않기에 사실상 final이다.
- 열거 타입 선언으로 만들어진 인스턴스들은 딱 하나씩만 존재함이 보장된다. => 즉 인스턴스 통제되며 싱글턴이다.
- 타입 안전성을 제공한다.
- namespace가 있어서 이름이 같은 상수도 공존할 수 있다.
- 임의의 메서드나 필드를 추가할 수 있고 임의의 인터페이스를 구현하게 할 수도 있다.
- 열거 타입은 자신 안의 정의된 상수들의 값을 배열에 담아 반환하는 정적메서드(values)를 제공한다.
Enum의 사용법 및 장점
-
열거 타입의 상수마다 다른 동작을 해야하는 경우.
public enum Operation { PLUS, MINUS, TIMES, DIVIDE; public double apply(double x, double y) { switch (this) { case PLUS: return x + y; case MINUS: return x - y; case TIMES: return x * y; case DIVIDE: return x / y; } throw new AssertionError("알 수 없는 연산: "+ this); } }위처럼 switch문을 사용 분기하는 방법을 할수 있다.
하지만, 새로운 새로운 상수의 추가 혹은 삭제시 매번 로직을 수정해야 해서 깨지기 쉽다.
public enum Operation { PLUS { @Override public double apply(double x, double y) { return x + y; } }, MINUS { @Override public double apply(double x, double y) { return x - y; } }, TIMES { @Override public double apply(double x, double y) { return x * y; } }, DIVIDE { @Override public double apply(double x, double y) { return x / y; } }; public abstract double apply(double x, double y); }열거 타입에 추상 메서드를 선언 후 각 상수별로 클래스 몸체(constant-specific class body)를 재정의하는 방법인데 이를 상수별 메서
드 구현(constant-specific method implementation)이라 한다.
-
데이터들 간의 연관관계 표현
-
상태와 행위를 한곳에서 관리
-
데이터 그룹 관리
-
필요한 원소를 컴파일타임에 다 알 수 있는 상수 집합이라면 항상 열거 타입을 사용하자.
-
전략 패턴 사용하자
public enum PayrollDay { MONDAY(WEEKDAY), TUESDAY(WEEKDAY), WEDNESDAY(WEEKDAY), THURSDAY(WEEKDAY), FRIDAY(WEEKDAY), SATURDAY(WEEKEND), SUNDAY(WEEKEND); private final PayType payType; PayrollDay(PayType payType) { this.payType = payType; } int pay(int minutesWorkd, int payRate) { return payType.pay(minutesWorkd, payRate); } enum PayType { WEEKDAY { @Override int overtimePay(int mins, int payRate) { return minWorked <= MINS_PER_SHIFT ? 0 : (minWorked - MINS_PER_SHIFT) * payRate / 2; } }, WEEKEND { @Override int overtimePay(int mins, int payRate) { return minsWorked * payRate / 2; } }; abstract int overtimePay(int mins, int payRate); private static final int MINS_PER_SHIFT = 8 * 60; int pay(int minsWorked, int payRate) { int basePay = minsWorked * payRate; return basePay + overtimePay(minsWorked, payRate); } } }
정리
• 열거 타입은 정수 상수보다 가독성과 안전성 부분에서 뛰어나다.
• 각 상수를 각각 다른 데이터와 동작과 연결시킬 수 있다.
• 하나의 메서드가 상수별로 다른 동작을 해야 할 경우 switch가 아니라 상수별 메서드 구현을 사용하자.
• 상수 몇몇이 같은 동작을 공유할 경우 전략 열거 타입 패턴을 사용하자.
참고