자바에서 enum(열거형)은 서로 연관된 상수들을 한 곳에 모아 관리할 수 있도록 해주는 특수한 데이터 타입입니다.
enum을 활용하면 코드의 가독성을 높이고, 실수를 줄이며, 유지보수를 편리하게 할 수 있습니다.
enum이 등장한 배경enum이 없던 시절 - 상수 선언 방식과거에는 enum이 없었기 때문에, 상수를 표현하는 여러 방법이 사용되었습니다.
static final int)가장 기본적인 방식은 static final int를 사용하는 것이었습니다.
class OrderStatus {
static final int PENDING = 0;
static final int SHIPPED = 1;
static final int DELIVERED = 2;
static final int CANCELLED = 3;
}
static final을 사용하면 변하지 않는 상수를 만들 수 있지만, 숫자로 표현되므로 의미가 불분명합니다. public class Main {
public static void main(String[] args) {
int status = 4; // 존재하지 않는 상태 값도 할당 가능 (0, 1, 2, 3 있음 / 4는 없음)
System.out.println("주문 상태: " + status);
}
}
4)도 할당할 수 있어 버그 발생 가능성이 높습니다.static final String)문자열(String)을 상수로 사용하는 방법도 생각해 볼 수 있겠습니다.
문자열을 상수로 선언하는 것은 가능하지만 비효율적이고, 오류 발생 가능성이 크기 때문에 잘 사용하지 않습니다.
class OrderStatus {
static final String PENDING = "PENDING";
static final String SHIPPED = "SHIPPED";
static final String DELIVERED = "DELIVERED";
static final String CANCELLED = "CANCELLED";
}
==을 사용할 수 없고, .equals()를 사용해야 합니다 (성능 저하).if (status.equals(OrderStatus.SHIPPED)) { // 올바른 비교
System.out.println("상품이 배송 중입니다.");
}
class OrderStatus {
static final OrderStatus PENDING = new OrderStatus("PENDING");
static final OrderStatus SHIPPED = new OrderStatus("SHIPPED");
static final OrderStatus DELIVERED = new OrderStatus("DELIVERED");
static final OrderStatus CANCELLED = new OrderStatus("CANCELLED");
private String name;
private OrderStatus(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
enum처럼 사용할 수 있지만, 여전히 제한적이며 불필요하게 길어진 코드가 많습니다.switch-case에서 사용할 수 없습니다 (switch문은 객체 타입을 사용할 수 없습니다).new 연산자를 사용하여 새로운 객체를 생성하면, 정의되지 않은(잘못된) 값을 만들 수 있습니다.new OrderStatus("INVALID") → 정의되지 않은(잘못된) 값enum을 사용하면 미리 정의된 값 외에는 생성할 수 없으므로, 값의 유효성이 보장됩니다.String) 상수 사용 시 문제점== 비교 불가능 (equals() 사용 필요)String status = OrderStatus.PENDING;
if (status == "PENDING") { // 오작동 가능
System.out.println("주문이 접수됨.");
}
== 연산자를 사용할 경우, 문자열이 동일한 객체인지를 비교합니다..equals()를 사용해야 합니다.String을 비교할 때는 모든 문자를 하나씩 비교해야 합니다. 반면, 정수 비교(== 연산자 사용)는 메모리에서 값을 비교할 수 있어 속도가 훨씬 빠릅니다.
비교 연산 속도는
int→enum→String순으로 성능이 좋습니다.
switch-case에서 문자열 사용이 제한적이었음 (Java 7 이전)과거 Java 7 이전에는 switch-case 문에서 String을 사용할 수 없었습니다 (Java 7부터 가능해짐).
Java 6에서는 switch 문에서 int, char, enum, byte, short 등의 타입만 지원했습니다.
// Java 6에서는 컴파일 오류 발생! (Java 7부터 가능)
public class Main {
public static void main(String[] args) {
String status = "PENDING"; // String 값
switch (status) { // ❌ Java 6에서는 String을 지원하지 않음!
case "PENDING":
System.out.println("주문이 접수되었습니다.");
break;
case "SHIPPED":
System.out.println("상품이 배송 중입니다.");
break;
}
}
}
error: incompatible types
found : java.lang.String
required: int
enum이 해결한 문제점enum은 위의 문제를 해결하기 위해 도입된 개념으로, 다음과 같은 장점이 있습니다.
enum을 사용하면 미리 정의된 값 외에는 입력할 수 없도록 제한됩니다. 기존 int 또는 String 상수 방식에서는 잘못된 값도 허용할 위험이 있었습니다.
하지만 enum은 컴파일러가 미리 정의된 값만 허용하도록 강제하므로, 오타나 잘못된 값을 방지할 수 있습니다.
즉, enum은 미리 정의된 값만 허용하므로, 오타나 잘못된 값 사용을 컴파일 타임에 방지할 수 있습니다.
기존에 int 또는 String을 상수로 사용하면 잘못된 값을 실수로 넣어도 컴파일러가 막지 못합니다.
public static final int STATUS_ACTIVE = 1;
public static final int STATUS_INACTIVE = 2;
int status = 3; // 잘못된 값이지만 컴파일 에러 없음
하지만 enum을 사용하면, 컴파일러가 enum에서 정의된 값만 허용하도록 강제합니다.
enum Status {
ACTIVE, INACTIVE;
}
Status status = Status.ACTIVE; // 정상
Status status2 = Status.PENDING; // 컴파일 에러! (PENDING이 정의되지 않음)
enum을 사용하면 코드만 봐도 어떤 값인지 직관적으로 이해할 수 있습니다.
숫자(int)기반 상수는 의미가 불분명하고, 문자열(String)은 오타 위험이 존재하지만, enum은 이런 문제를 해결합니다.
class Order {
static final int PENDING = 0;
static final int SHIPPED = 1;
static final int DELIVERED = 2;
static final int CANCELLED = 3;
}
// 어떤 의미인지 직관적으로 알기 어려움
int status = 1;
if (status == 2) { // 이게 배송 완료인지 바로 이해되지 않음
System.out.println("배송 완료");
}
enum을 사용한 경우 (직관적)enum OrderStatus {
PENDING, SHIPPED, DELIVERED, CANCELLED;
}
// 코드만 봐도 의미가 명확함
OrderStatus status = OrderStatus.SHIPPED;
if (status == OrderStatus.DELIVERED) {
System.out.println("배송 완료");
}
enum을 사용하면 코드를 읽는 사람도 쉽게 이해할 수 있어 유지보수성이 향상됩니다.== 연산자 사용 가능 → 문자열 비교보다 성능이 좋음enum은 내부적으로 싱글톤 객체처럼 동작하므로, == 연산자로 비교가 가능합니다.
반면, String을 사용하면, .equals()를 사용해야 하며, 객체 주소를 비교하면 오류가 발생할 수 있습니다.
⚠️주의:
enum은 싱글톤처럼 동작하지만, 싱글톤 패턴은 아닙니다.
String을 사용할 경우 (== 사용 불가, .equals() 사용)String status = "SHIPPED";
if (status == "SHIPPED") { // ❌ 오작동 가능 (객체 주소 비교)
System.out.println("상품이 배송 중입니다.");
}
if (status.equals("SHIPPED")) { // ✅ 문자열 비교는 equals() 사용
System.out.println("상품이 배송 중입니다.");
}
String에서 == 비교를 하면 객체 주소를 비교하므로 오작동 가능성이 있습니다..equals()를 사용해야 하는 번거로움이 있습니다.enum을 사용한 경우 (== 연산자 사용 가능)OrderStatus status = OrderStatus.SHIPPED;
if (status == OrderStatus.SHIPPED) { // status는 OrderStatus.SHIPPED와 동일한 객체
System.out.println("상품이 배송 중입니다.");
}
enum의 각 값(SHIPPED, PENDING 등)은 미리 만들어진 단 하나의 객체이므로, ==로 비교해도 항상 같은 객체임을 보장합니다..equals()를 사용하지 않고 == 연산자로 비교할 수 있어 성능도 향상됩니다 (불필요한 연산 줄임)..equals()를 호출해야 값이 같은지 확인할 수 있지만, enum은 같은 객체이므로 굳이 .equals()를 호출할 필요 없이 == 비교만 해도 됩니다.enum을 사용하면 잘못된 값 자체를 넣을 수 없으므로, 컴파일 단계에서 오류를 방지할 수 있습니다.
반면, int나 String을 사용하면 잘못된 값이 들어가도 컴파일러가 경고하지 않습니다 (컴파일 단계에서 오류를 체크할 수 없음).
int 상수 사용 (잘못된 값이 들어가도 컴파일러가 알 수 없음)int status = 5; // ❌ 존재하지 않는 상태 값도 들어갈 수 있음
enum을 사용한 경우 (잘못된 값 자체를 넣을 수 없어 컴파일 단계에서 오류 방지)// ❌ 기존의 int 기반 방식 (잘못된 값이 들어가도 컴파일 오류 없음)
int status = 5; // 잘못된 값이지만 컴파일 오류 없음 (런타임 오류 가능성 있음)
// ✅ enum 사용 (잘못된 값 자체가 들어갈 수 없음)
OrderStatus status = OrderStatus.SHIPPED; // 정상
// OrderStatus wrongStatus = 5; // ❌ 컴파일 오류 발생 (잘못된 값 허용 불가)
enum은 단순한 상수가 아니라, 클래스처럼 필드와 메서드를 가질 수 있습니다.
즉, 각 enum 값마다 특정한 속성(값)을 가질 수 있도록 만들 수 있으며, 또한, 필드 값을 가져오는 메서드를 추가하여, 객체처럼 동작할 수 있습니다.
enum OrderStatus {
PENDING("주문 접수"), SHIPPED("배송 중"), DELIVERED("배송 완료"), CANCELLED("주문 취소");
private final String description; // ✅ 각 상태에 대한 설명을 저장할 필드
// ✅ 생성자 (각 enum 값이 생성될 때 description을 초기화)
OrderStatus(String description) {
this.description = description;
}
// ✅ 필드 값을 반환하는 메서드
public String getDescription() {
return description;
}
}
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.SHIPPED;
// ✅ 각 enum 값의 description을 가져오기
System.out.println(status.getDescription()); // 출력: 배송 중
}
}
enum 값마다 특정한 속성(값)을 추가할 수 있음
enum에 추가하는 속성(필드)의 타입에는 제한이 없습니다.int, String, double, boolean, List, Map그리고 사용자 정의 클래스까지 모두 가능합니다.
PENDING("주문 접수"), SHIPPED("배송 중"), DELIVERED("배송 완료"), CANCELLED("주문 취소");
enum 값은 특정한 데이터를 함께 가질 수 있도록 설계되었습니다.private final 필드로 데이터 저장private final String description;
enum 값에 대한 설명을 저장하는 역할을 합니다.final이므로, 한 번 설정되면 변경할 수 없습니다 (불변 객체).enum 생성자를 사용해 값 초기화OrderStatus(String description) {
this.description = description;
}
enum 값이 생성될 때 description을 초기화합니다.public String getDescription() {
return description;
}
OrderStatus.SHIPPED.getDescription()을 호출하면 "배송 중"을 반환합니다.switch-case에서 사용 가능 → enum은 내부적으로 정수 값을 가지므로 switch-case에서 문제없이 동작함자바의 switch-case 문은 기본적으로 정수(int), 문자(char), 문자열(String - Java 7 이상), 그리고 enum만 지원합니다.
특히, enum은 객체임에도 불구하고 switch-case에서 예외적으로 사용할 수 있습니다.
이는 enum이 내부적으로 ordinal() 값을 가지며, 이 값이 정수처럼 동작하기 때문입니다.
ordinal()은 enum 값이 선언된 순서(0부터 시작하는 정수)를 반환합니다.switch-case에서 enum을 사용할 때, 내부적으로 ordinal() 값을 기반으로 비교 연산이 수행됩니다.즉, 일반 객체는
switch-case에서 사용할 수 없지만,enum은 내부적으로 정수(ordinal())를 가지기 때문에 예외적으로 지원됩니다.
enum OrderStatus {
PENDING, PROCESSING, SHIPPED, DELIVERED;
}
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.SHIPPED;
switch (status) {
case PENDING:
System.out.println("주문이 보류 중입니다.");
break;
case PROCESSING:
System.out.println("주문을 처리 중입니다.");
break;
case SHIPPED:
System.out.println("상품이 배송 중입니다.");
break;
case DELIVERED:
System.out.println("상품이 도착했습니다.");
break;
}
}
}
switch(status) → status.ordinal()을 내부적으로 변환 (즉, switch(2)처럼 동작)ordinal() 값을 기반으로 분기 처리즉, 아래와 같이 변환된다고 볼 수 있습니다:
switch (status.ordinal()) {
case 0:
System.out.println("주문이 보류 중입니다.");
break;
case 1:
System.out.println("주문을 처리 중입니다.");
break;
case 2:
System.out.println("상품이 배송 중입니다.");
break;
case 3:
System.out.println("상품이 도착했습니다.");
break;
}
switch-case 사용 불가)class OrderStatus {
static final OrderStatus PENDING = new OrderStatus("PENDING");
static final OrderStatus SHIPPED = new OrderStatus("SHIPPED");
}
// ❌ switch-case에서 사용 불가능 (객체 타입이라서 오류 발생)
switch (status) {
case OrderStatus.PENDING:
System.out.println("주문이 접수되었습니다.");
break;
}
switch-case에서 사용할 수 없습니다.switch-case에서 정상 동작)enum OrderStatus {
PENDING, SHIPPED, DELIVERED, CANCELLED;
}
switch (status) {
case PENDING:
System.out.println("주문이 접수되었습니다.");
break;
}
enum은 내부적으로 정수 값을 가지므로 switch-case에서 사용 가능합니다.enum이 내부적으로 정수 값을 가진다는 말의 의미enum 자체는 객체(인스턴스)이며, 직접적으로 정수 값을 가지지는 않습니다.
하지만 JVM 내부적으로 enum 값에 자동으로 정수 값(ordinal, 순서값)을 부여합니다.
enum OrderStatus {
PENDING, PROCESSING, SHIPPED, DELIVERED;
}
public class Main {
public static void main(String[] args) {
System.out.println(OrderStatus.PENDING.ordinal()); // 0
System.out.println(OrderStatus.PROCESSING.ordinal()); // 1
System.out.println(OrderStatus.SHIPPED.ordinal()); // 2
System.out.println(OrderStatus.DELIVERED.ordinal()); // 3
}
}
0
1
2
3
ordinal() 메서드를 호출하면 JVM이 자동으로 부여한 정수 값(0부터 시작하는 순서값)을 반환하는 걸 확인할 수 있습니다.ordinal() 값을 직접 사용하는 것은 권장되지 않습니다.enum의 내부 동작 (JVM에서 어떻게 처리되는가?) 자바의 enum은 내부적으로 클래스로 변환됩니다. 즉, 우리가 enum을 선언하면 컴파일 시점에 final 클래스가 자동으로 생성되며, 해당 클래스의 각 enum 값은 public static final 객체로 정의됩니다.
또한, enum은 싱글톤처럼 관리되어, 동일한 값이 여러 개 생성되지 않고 프로그램 실행 동안 하나의 인스턴스만 유지됩니다.
컴파일러는 enum에 대해 두 가지 유용한 메서드를 자동으로 생성합니다.
values(): 모든 enum 값을 배열로 반환 valueOf(String name): 문자열 이름을 기반으로 enum 값을 반환 또한, 각 enum 값은 내부적으로 순서(ordinal)를 가지며, 이는 0부터 시작합니다.
즉, enum은 클래스로 변환되어 정적인 객체로 관리되며, 특정 순서 값을 가지면서도 타입 안정성을 제공하는 구조라고 볼 수 있습니다.
enum의 구조 설명enum 자체가 하나의 클래스입니다. 이 클래스는 java.lang.Enum 클래스를 암묵적으로 상속받습니다.enum 클래스 내부에 선언된 PENDING, SHIPPED 등의 각 상수는 실제로 해당 enum 타입의 고유한 인스턴스(객체)입니다.enum 상수는 static final 필드로 선언된 것과 같은 효과를 가지며, 클래스가 로드될 때 초기화됩니다.enum 값에 접근하는 방법enum 값은 static final로 선언된 정적 상수 객체처럼 동작하므로, 클래스명.값 형식으로 접근해야 합니다.
enum OrderStatus {
PENDING, SHIPPED, DELIVERED, CANCELLED;
}
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.SHIPPED; // ✅ enum 값 접근
System.out.println(status); // 출력: SHIPPED
}
}
OrderStatus.SHIPPED는 미리 정의된 정적 상수 객체를 참조하는 방식으로 동작합니다.new 없이 OrderStatus.SHIPPED처럼 직접 접근합니다.enum이 싱글톤처럼 동작하는 이유enum은 내부적으로 JVM이 클래스 로딩 시 자동으로 생성하고 관리합니다. 따라서, 한 번만 생성되며, 여러 번 호출해도 동일한 객체를 반환합니다.
즉,
enum은 싱글톤 패턴과 유사하게 동작합니다.
public class Main {
public static void main(String[] args) {
OrderStatus status1 = OrderStatus.SHIPPED;
OrderStatus status2 = OrderStatus.SHIPPED;
System.out.println(status1 == status2); // true (같은 객체)
}
}
OrderStatus.SHIPPED를 여러 번 호출해도 항상 같은 객체를 반환합니다.enum 값은 프로그램 실행 동안 동일한 인스턴스를 유지합니다.new를 사용하여 enum 객체를 생성할 수 없는 이유enum은 JVM이 미리 생성하여 관리하므로, new를 사용할 필요가 없습니다.
또한, enum의 생성자는 자동으로 private이므로, 외부에서 객체 생성이 불가합니다.
new 연산자로 생성 시 오류 발생OrderStatus status = new OrderStatus(); // ❌ 컴파일 오류 발생!
enum 값은 미리 생성되어 있기 때문에, new로 새로운 객체를 만들 수 없습니다.OrderStatus.SHIPPED 같은 방식으로만 사용할 수 있습니다 (참조 방식).enum을 클래스로 변환한 코드 예제다음 enum을 선언하면:
enum OrderStatus {
PENDING, SHIPPED, DELIVERED, CANCELLED;
}
JVM은 내부적으로 다음과 같은 클래스로 변환합니다:
// 실제 코드는 아니지만, 개념적으로 이해하기 위한 유사 코드
public final class OrderStatus extends Enum<OrderStatus> {
public static final OrderStatus PENDING = new OrderStatus("PENDING", 0);
public static final OrderStatus SHIPPED = new OrderStatus("SHIPPED", 1);
public static final OrderStatus DELIVERED = new OrderStatus("DELIVERED", 2);
public static final OrderStatus CANCELLED = new OrderStatus("CANCELLED", 3);
// private 생성자 - 외부에서 new로 생성 불가
private OrderStatus(String name, int ordinal) {
super(name, ordinal);
}
private static final OrderStatus[] VALUES = { PENDING, SHIPPED, DELIVERED, CANCELLED };
// values(): 모든 enum 값을 배열로 반환
public static OrderStatus[] values() {
return VALUES.clone();
}
// valueOf(String name): 문자열 이름을 기반으로 enum 값을 반환
public static OrderStatus valueOf(String name) {
for (OrderStatus status : VALUES) {
if (status.name().equals(name)) {
return status;
}
}
throw new IllegalArgumentException("No enum constant " + name);
}
}
OrderStatus는 Enum<OrderStatus>를 상속하는 final 클래스로 변환됩니다.enum 값은 public static final 객체로 선언되며, 생성자를 통해 초기화됩니다.values() 메서드는 모든 enum 값을 배열로 반환합니다.valueOf(String name) 메서드는 이름을 기반으로 enum 값을 찾습니다.enum은 내부적으로 싱글턴 객체 집합처럼 동작하며, 인스턴스를 추가로 생성할 수 없습니다.Enum과 enum의 차이Enum(대문자) → 자바의 Enum<T> 클래스 (모든 enum이 자동으로 상속받는 부모 클래스)enum(소문자) → 자바의 열거형(enum) 키워드 (새로운 열거형을 정의할 때 사용)즉,
enum은 키워드이고,Enum은 클래스입니다.
enum (소문자)enum은 자바에서 열거형을 정의할 때 사용하는 키워드입니다.class, interface처럼 사용자가 새로운 열거형을 만들 때 사용합니다.enum OrderStatus {
PENDING, SHIPPED, DELIVERED, CANCELLED;
}
enum은 새로운 열거형 OrderStatus를 정의하는 데 사용됩니다.Enum<T> (대문자)Enum<T>는 모든 enum이 자동으로 상속받는 부모 클래스입니다.enum을 선언하면, JVM이 자동으로 Enum<T> 클래스를 확장(상속)합니다.자바에서
enum을 선언하면, 내부적으로extends Enum<T>가 자동 추가됩니다.
enum OrderStatus extends Enum<OrderStatus> { // 내부적으로 이렇게 변환됨!
PENDING, SHIPPED, DELIVERED, CANCELLED;
}
Enum<OrderStatus> 클래스를 상속받습니다.enum은 Enum<T>의 기능을 사용할 수 있습니다.Enum<T> 클래스가 제공하는 기능Enum<T> 클래스는 모든 enum에서 사용할 수 있는 유용한 메서드를 제공합니다.
❗️
name(),ordinal(),values(),valueOf()메서드 정리
name()→ enum 값의 문자열 이름 반환 ("SHIPPED")ordinal()→ enum 값의 순서(0부터 시작) (1)values()→ 모든 enum 값을 배열로 반환valueOf(String name)→ 문자열과 일치하는 기존 enum 객체를 찾아 반환
Enum<T> 클래스가 제공하는 메서드 정리| 메서드 | 설명 |
|---|---|
| name() | enum 값의 문자열 이름을 반환 ("SHIPPED") |
| ordinal() | enum 값의 순서(0부터 시작) 반환 (1) |
| values() | 모든 enum 값을 배열로 반환 |
| valueOf(String name) | 문자열을 enum 값으로 변환 ("DELIVERED" → OrderStatus.DELIVERED) |
name() → enum 값의 이름 반환name() 메서드는 각 enum 값의 이름을 문자열로 반환합니다.
enum OrderStatus {
PENDING, SHIPPED, DELIVERED, CANCELLED;
}
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.SHIPPED;
System.out.println(status.name()); // 출력: SHIPPED
}
}
SHIPPED
ordinal() → enum 값의 순서 반환ordinal() 메서드는 각 enum 값의 순서를 0부터 시작하는 정수로 반환합니다.
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.SHIPPED;
System.out.println(status.ordinal()); // 출력: 1
}
}
1
SHIPPED.ordinal()을 호출하면 enum 선언 순서에서 1번째이므로 1이 반환됨.values() → 모든 enum 값을 배열로 반환values() 메서드는 enum에 정의된 모든 값을 배열로 반환합니다.
배열을 순회하면서 모든 enum 값을 출력할 수 있습니다.
public class Main {
public static void main(String[] args) {
for (OrderStatus os : OrderStatus.values()) {
System.out.println(os);
}
}
}
PENDING
SHIPPED
DELIVERED
CANCELLED
values()는 OrderStatus[] 배열을 반환하며, 배열을 순회하여 모든 값을 출력할 수 있습니다.valueOf(String name) → 문자열과 일치하는 기존 enum 객체를 반환valueOf(String name) 메서드는 문자열과 일치하는 기존 enum 객체를 반환합니다.
단, 대소문자가 정확히 일치해야 하며, 존재하지 않는 값이면 예외가 발생합니다.
public class Main {
public static void main(String[] args) {
OrderStatus fromString = OrderStatus.valueOf("DELIVERED");
System.out.println(fromString); // 출력: DELIVERED
}
}
DELIVERED
OrderStatus.DELIVERED 객체를 반환합니다.OrderStatus invalid = OrderStatus.valueOf("delivered"); // ❌ 오류 발생 (대소문자 일치해야 함)
IllegalArgumentException이 발생합니다.enum 선언 방식자바에서 enum(열거형)은 특정한 상수 집합을 정의하는 특수한 클래스입니다.
enum은 일반적인 클래스처럼 필드, 생성자, 메서드를 가질 수 있으며, 다양한 방식으로 선언할 수 있습니다.
enum 선언가장 간단한 enum 선언 방식은 값만 정의하는 형태입니다.
enum OrderStatus {
PENDING, SHIPPED, DELIVERED, CANCELLED;
}
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.SHIPPED;
System.out.println(status); // 출력: SHIPPED
}
}
enum 값(PENDING, SHIPPED 등)은 OrderStatus의 인스턴스(객체)로 존재합니다.static final 객체입니다.enum에 필드(속성)와 생성자 추가enum은 단순한 값뿐만 아니라, 필드(속성)와 생성자를 가질 수 있습니다.
이를 통해 각 enum 값마다 고유한 데이터를 저장할 수 있습니다.
enum OrderStatus {
PENDING("주문 접수"),
SHIPPED("배송 중"),
DELIVERED("배송 완료"),
CANCELLED("주문 취소");
private final String description; // ✅ 각 상태에 대한 설명 필드
// ✅ 생성자
OrderStatus(String description) {
this.description = description;
}
// ✅ 필드 값을 반환하는 메서드
public String getDescription() {
return description;
}
}
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.SHIPPED;
System.out.println(status.getDescription()); // 출력: 배송 중
}
}
enum 값이 생성될 때, description 필드가 함께 초기화됩니다.enum이 단순한 상수가 아니라, 객체처럼 활용 가능합니다.enum에 여러 개의 필드 추가enum 값마다 여러 개의 속성을 가질 수도 있습니다.
아래 예제에서는 코드 값(int)과 설명(String)을 함께 저장합니다.
enum OrderStatus {
PENDING(0, "주문 접수"),
SHIPPED(1, "배송 중"),
DELIVERED(2, "배송 완료"),
CANCELLED(3, "주문 취소");
private final int code;
private final String description;
OrderStatus(int code, String description) {
this.code = code;
this.description = description;
}
public int getCode() { return code; }
public String getDescription() { return description; }
}
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.DELIVERED;
System.out.println("코드: " + status.getCode()); // 출력: 코드: 2
System.out.println("설명: " + status.getDescription()); // 출력: 설명: 배송 완료
}
}
enum 값이 int와 String 속성을 가질 수 있습니다.enum을 단순한 상수가 아니라, 객체처럼 사용할 수 있도록 확장 가능합니다.enum에 메서드 추가enum 내부에 메서드를 추가하여 특정 로직을 수행할 수도 있습니다.
enum OrderStatus {
PENDING(0, "주문 접수"),
SHIPPED(1, "배송 중"),
DELIVERED(2, "배송 완료"),
CANCELLED(3, "주문 취소");
private final int code;
private final String description;
OrderStatus(int code, String description) {
this.code = code;
this.description = description;
}
public int getCode() { return code; }
public String getDescription() { return description; }
// ✅ 특정 코드값으로 `enum`을 찾는 메서드 추가
public static OrderStatus fromCode(int code) {
for (OrderStatus status : OrderStatus.values()) { // OrderStatus.values() → OrderStatus 객체 배열 반환
if (status.getCode() == code) {
return status;
}
}
throw new IllegalArgumentException("잘못된 코드 값: " + code);
}
}
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.fromCode(1);
System.out.println(status); // 출력: SHIPPED
}
}
fromCode(int code) 메서드를 통해 코드 값으로 enum을 찾을 수 있습니다.enum을 활용하면 코드가 더 직관적이고 유지보수하기 쉬워집니다.enum 값별로 메서드 오버라이딩각 enum 값마다 서로 다른 동작을 수행하도록 오버라이딩할 수 있습니다.
enum OrderStatus {
PENDING {
@Override
public String getMessage() { return "주문이 접수되었습니다."; }
},
SHIPPED {
@Override
public String getMessage() { return "상품이 배송 중입니다."; }
},
DELIVERED {
@Override
public String getMessage() { return "상품이 도착했습니다."; }
},
CANCELLED {
@Override
public String getMessage() { return "주문이 취소되었습니다."; }
};
// ✅ 기본 메시지 메서드 (추상 메서드)
public abstract String getMessage();
}
public class Main {
public static void main(String[] args) {
OrderStatus status = OrderStatus.SHIPPED;
System.out.println(status.getMessage()); // 출력: 상품이 배송 중입니다.
}
}
enum 값에서 메서드를 오버라이딩하면, switch-case 없이도 특정한 동작을 수행할 수 있습니다.switch-case를 없애고 enum 자체의 기능을 활용할 수 있습니다.