1. enum이란?
- JDK1.5부터 도입된 연관된 상수(Constant)들의 집합을 정의하는 특수 클래스
- 예를 들어 아래처럼 값이 정해져 있고 바뀌지 않는 경우 사용!!
- 요일 (월, 화, 수, 목, 금, 토, 일)
- 연산자 (+, -, *, /)
- 상태값 (READY, RUNNING, STOP)
2. enum을 사용하지 않을 경우의 단점
[문자열을 이용한 방식의 문제]
public class MemberService {
public int discount(String grade, int price) {
if (grade.equals("BASIC")) {
return price - 1000;
} else if (grade.equals("VIP")) {
return price - 2000;
}
return price;
}
}
- 오타 발생 가능 (오타가 발생하여도 컴파일 시점에서 검출 불가)
- 파라미터에 미리 정해둔 값이 아닌 임의의 문자열 입력 가능
[상수를 이용한 방식의 문제]
public class MemberGrade {
public static final String BASIC = "BASIC";
public static final String VIP = "VIP";
}
public class MemberService {
public int discount(String grade, int price) {
if (grade.equals(MemberGrade.BASIC)) {
return price - 1000;
} else if (grade.equals(MemberGrade.VIP)) {
return price - 2000;
}
return price;
}
}
- 문자열 오타는 방지하였으나 문자열 상수를 사용하기 때문에 어떠한 문자든 입력 가능
[Java 클래스를 통해 열거형을 구현하는 방식]
public class MemberGrade {
public static final MemberGrade BASIC = new MemberGrade("BASIC");
public static final MemberGrade VIP = new MemberGrade("VIP");
private final String grade;
private MemberGrade(String grade) {
this.grade = grade;
}
public String getGrade() {
return grade;
}
}
- 외부에서 MemberGrade 객체를 생성할 수 없으므로 BASIC, VIP 로 고정
- 그 이외에도 아래와 같은 단점 존재
- switch문 사용 불가 (자바의 switch는 enum을 지원하지만 일반 클래스 타입은 지원하지 않음)
- toString(), values() 같은 기본적인 유틸리티 메서드 제공하지 않아, 직접 구현
- java 직렬화시 역직렬화로 인한 중복 인스턴스 생성 문제
3. enum 주요 메서드 정리
Java의 enum은 기본적으로 여러 유용한 메서드 제공
3-1. values()
3-2. valueOf(String name)
OperatorType op = OperatorType.valueOf("ADD");
System.out.println(op);
- 출력
ADD
- 대소문자 정확히 일치해야 함(틀리면 IllegalArgumentException 발생)
3-3. ordinal()
System.out.println(OperatorType.ADD.ordinal());
System.out.println(OperatorType.SUBTRACT.ordinal());
3-4. name()
OperatorType op = OperatorType.ADD;
System.out.println(op.name());
ADD
3-5. toString()
- 기본적으로 name()과 동일하나 오버라이드해서 커스터마이징 가능
@Override
public String toString() {
return "연산자: " + symbol;
}
연산자: +
4. enum 사용법
4-1. 기본 정의 방법
public enum OperatorType { ADD, SUBTRACT, MULTIPLY, DIVIDE }
- 특징
- enum 키워드로 선언
- 클래스처럼 이름 가짐
- 내부에는 상수 정의
- 보통 상수는 대문자로 작성
4-2. 기본 사용법
OperatorType op = OperatorType.ADD;
System.out.println(op); => ADD 출력
4-3. enum에 값(필드) 넣기
- enum은 단순한 상수 묶음이 아니라 값 저장 가능
public enum OperatorType {
ADD('+'),
SUBTRACT('-');
private final char symbol;
OperatorType(char symbol) {
this.symbol = symbol;
}
public char getSymbol() {
return symbol;
}
}
- ADD('+') -> 생성자로 값 전달
- 각 enum은 자신만의 값을 가짐
- getter로 꺼내서 사용 가능
4-4. enum에 메서드 넣기
public char getSymbol() { return symbol; }
- 단순 데이터가 아니라 데이터+기능을 할께 가지는 구조
4-5. enum 상수마다 다른 동작 정의하기
public enum OperatorType {
ADD('+') {
@Override
public double calculate(double num1, double num2) {
return num1 + num2;
}
},
SUBTRACT('-') {
@Override
public double calculate(double num1, double num2) {
return num1 - num2;
}
};
private final char symbol;
OperatorType(char symbol) {
this.symbol = symbol;
}
public abstract double calculate(double num1, double num2);
}
- 각 enum이 서로 다른 동작을 가짐
- if, switch 없이 로직 처리 가능
4-9. 값으로 enum 찾기
- 사용자가 입력한 값을 enum으로 바꿀 때 사용
public static OperatorType fromChar(char ch) {
for (OperatorType op : OperatorType.values()) {
if (op.symbol == ch) {
return op;
}
}
throw new IllegalArgumentException("지원하지 않는 연산자입니다.");
}
- values() -> enum 전체 조회하여 반복문으로 매칭
5. enum 주요 특징
- 정해진 값만 사용 가능
- 하나의 타입으로 사용 가능
- 필드, 생성자, 메서드 정의 가능
- 상수마다 다른 동작 정의 가능
- 코드 안정성과 가독성 향상
6. enum 사용 시 주의할 점
- 값이 계속 변하는 경우에는 적합하지 않음
- 사용자 입력을 그대로 enum으로 쓰면 오류 발생
출처
출처 : https://ywoosang.tistory.com/28