JAVA (5) - Enum
JAVA (5) - Enum
1. 개요
열거형(Enum, Enumeration)은 서로 관련이 있는 연관된 상수들의 집합을 정의하는 특수한 데이터 타입이다.
Java 5 이전에는 상수를 정의할 때 final static int 방식을 사용했지만, 이는 타입 안정성 문제나 가독성 저하를 유발했다. Enum을 활용하면 정해진 값 모음 이외의 잘못된 값이 들어오는 것을 컴파일 시점에 방지할 수 있고, 코드의 의미를 명확하게 전달할 수 있다.
2. Enum의 필요성: 기존 상수의 문제점
기존에 public static final을 이용해 상수를 정의하던 방식을 살펴보자.
1
2
3
4
5
6
7
8
9
public class DayConstant {
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
}
public class MonthConstant {
public static final int JANUARY = 1;
}
이 방식은 두 가지 큰 문제점을 가진다.
- 타입 안전성(Type Safety) 부족:
DayConstant.MONDAY와MonthConstant.JANUARY는 둘 다 값이1이므로MONDAY == JANUARY가 참이 되는 논리적 오류가 발생한다. - 범위 외의 값 입력 방지 불가: 메서드의 매개변수로
DayConstant중 하나를 받고 싶어도 타입이int이기 때문에 정수999같은 엉뚱한 값이 전달되어도 컴파일 에러를 잡아내지 못한다.
3. Enum의 선언과 기본 사용법
Enum을 선언할 때는 class 대신 enum 키워드를 사용한다.
1
2
3
4
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class EnumTest {
public static void main(String[] args) {
Day today = Day.FRIDAY;
// 타입 안정성 보장: Day 타입에 속한 값만 대입할 수 있다.
if (today == Day.FRIDAY) {
System.out.println("금요일이다!");
}
// switch 문에서의 활용
switch (today) {
case MONDAY -> System.out.println("월요일");
case FRIDAY -> System.out.println("금요일");
default -> System.out.println("평일 또는 주말");
}
}
}
4. Enum이 제공하는 주요 메서드
Java의 모든 Enum은 내장 클래스인 java.lang.Enum을 상속받으므로 유용한 기본 메서드들을 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Day today = Day.WEDNESDAY;
// 1. name(): Enum 상수의 이름을 문자열로 반환한다.
String name = today.name(); // "WEDNESDAY"
// 2. ordinal(): Enum 상수가 정의된 순서(0부터 시작)를 반환한다.
int ordinal = today.ordinal(); // 2
// 3. values(): Enum에 정의된 모든 상수를 배열로 반환한다.
Day[] days = Day.values();
for (Day d : days) {
System.out.println(d);
}
// 4. valueOf(String name): 주어진 문자열과 일치하는 Enum 상수를 반환한다.
Day day = Day.valueOf("MONDAY");
주의:
ordinal()은 상수의 선언 순서에 의존하므로 상수의 순서가 바뀌면 예기치 않은 버그가 발생할 수 있다. 실무에서는ordinal()에 의존하는 로직을 작성하지 않는 것이 바람직하다.
5. Enum에 필드와 메서드 추가하기
Java의 Enum은 단순한 상수의 집합을 넘어 일반 클래스처럼 필드, 생성자, 메서드를 가질 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public enum PayType {
CARD("신용카드", 0.0),
ACCOUNT_TRANSFER("계좌이체", 0.005),
MOBILE("휴대폰 결제", 0.02);
// 필드 선언 (불변성을 위해 final 권장)
private final String description;
private final double feeRate;
// 생성자 (Enum 생성자는 기본적으로 private)
PayType(String description, double feeRate) {
this.description = description;
this.feeRate = feeRate;
}
// Getter 메서드
public String getDescription() {
return description;
}
// 수수료 계산 로직 추가
public double calculateFee(int amount) {
return amount * feeRate;
}
}
1
2
3
4
5
6
7
8
9
public class PayTest {
public static void main(String[] args) {
PayType pay = PayType.MOBILE;
System.out.println("결제 수단: " + pay.getDescription()); // 휴대폰 결제
System.out.println("수수료: " + pay.calculateFee(10000)); // 200.0
}
}
6. 정리
- Enum은 연관된 상수들을 안전하고 깔끔하게 관리하기 위해 사용한다.
- 컴파일 타임에 타입 체크가 이루어지므로 잘못된 값이 들어오는 상황을 완벽히 방지한다.
- 데이터와 관련된 연산 로직을 Enum 내부에 상태와 행위(필드와 메서드)로 묶어서 관리할 수 있으므로 코드의 객체지향적 설계와 가독성이 향상된다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.