Enum이란 특정한 이름이 있는 상수들의 집합을 정의하는 클래스이다.
Enum은 주로 코드의 가독성을 높이고, 상수들에 대한 관리를 쉽게 하며, 타입 안전성을 확보하기 위해 사용된다.
상수를 정의하기 위해서 final을 사용할 수도 있는데, Enum을 사용하면 어떤 이점이 있을지 알아보도록 하겠다.
final 변수는 인스턴스 변수, 지역 변수, 또는 매개변수로 사용할 수 있으며, 한 번 초기화되면 더 이상 값을 변경할 수 없다.
public class FinalExample {
public final int instanceVariable;
public FinalExample(int value) {
this.instanceVariable = value; // 초기화 후 변경 불가
}
public void method(final int parameter) {
final int localVariable = parameter;
// localVariable = 10; // 컴파일 오류: final 변수는 재할당할 수 없음
}
}
final을 사용하면 한 번 설정된 값을 변경할 수 없으므로, 코드의 신뢰성이 높아지고, 상태가 변하지 않는 객체를 만들 수 있다.
또한, 특정 값이 변경되지 않도록 보장하여, 실수로 인한 값을 변경하는 것을 방지한다.
즉, 불변성(Immutability)과 안정성(Stability)을 보장할 수 있다.
static final 변수는 클래스 수준에서 상수를 정의한다. 이는 특정 클래스의 모든 인스턴스가 공유하는 상수 값이다.
public class StaticFinalExample {
public static final int CONSTANT = 100;
}
이렇게 선언했을 때는 전역 상수로 클래스 로딩 시 초기화되며, 모든 인스턴스가 동일한 값을 공유하게 된다. 상수 값을 한 곳에서 관리할 수 있고 상수 값이 클래스 하나에만 존재하므로 메모리를 절약할 수 있다는 장점이 있다.
그럼 Enum을 사용했을 때는 위의 final과 비교해서 어떤 이점이 있을까.
요일을 상수로 표현할 때를 예를 들어보면,
public class DayFinal {
public final int SUNDAY = 0;
public final int MONDAY = 1;
public final int TUESDAY = 2;
public final int WEDNESDAY = 3;
public final int THURSDAY = 4;
public final int FRIDAY = 5;
public final int SATURDAY = 6;
public static void main(String[] args) {
DayFinal dayFinal = new DayFinal();
System.out.println(dayFinal.MONDAY); // 1 출력
}
}
요일을 final만을 사용해서 정의하면, 각 instance마다 상수 값이 존재하게 되므로 전역적으로 접근하는 게 불가능하고 각 instance마다 상수값이 메모리에 할당되므로 메모리가 낭비된다.
public class DayStaticFinal {
public static final int SUNDAY = 0;
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
public static final int THURSDAY = 4;
public static final int FRIDAY = 5;
public static final int SATURDAY = 6;
public static void main(String[] args) {
System.out.println(DayStaticFinal.MONDAY); // 1 출력
}
}
static final로 요일을 정의한다면, 모든 instance가 같은 값을 공유하게 되고 메모리를 절약할 수 있어 적절한 방법이라고 볼 수 있다.
하지만, 각 요일에 대한 값이 정수로 표현되기 때문에 다른 정수형 값들과 혼동될 여지가 있고 그로인해 타입 안정성이 부족하다.
public enum DayEnum {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}
public class Main {
public static void main(String[] args) {
DayEnum today = DayEnum.MONDAY;
System.out.println(today); // MONDAY 출력
// 모든 요일 순회
for (DayEnum day : DayEnum.values()) {
System.out.println(day);
}
}
}
Enum을 사용한다면, 상수 값을 그룹화하고 각 값에 적절한 의미를 부여할 수 있기 때문에 타입 안정성을 보장할 수 있다.
정리하면 아래와 같은 장점을 가지게 된다.
- 타입 안전성: DayEnum 타입만 사용 가능, 잘못된 값 사용 방지.
- 가독성: 코드의 의미를 더 잘 표현.
- 추가 기능 제공: values(), valueOf(), ordinal() 등의 메서드 제공.
- 추가 필드 및 메서드 가능: 더 복잡한 로직을 구현 가능.
특성 | final | static final | enum |
전역적 접근 | 불편함 | 용이 | 용이 |
메모리 효율성 | 낮음 | 높음 | 높음 |
타입 안전성 | 없음 | 없음 | 있음 |
가독성 | 낮음 | 보통 | 높음 |
추가 기능 | 없음 | 없음 | 있음 (메서드, 필드 등 추가 가능) |