☕️ 김영한의 실전 자바 - 중급 1편 을 듣고 작성하는 복습 블로그 입니다.
0. 배경
상태나 정해진 값을 나타내기 위해서 자바에서 enum 을 많이 사용한다
이번엔 enum 이 생겨나게 된 이유부터 어떻게 사용하면 되는지 알아보자 !!
1. 고객 등급 구현하기
고객을 3개의 등급으로 나누고, 상품을 구매할 때 등급별로 할인을 적용하려고 한다
🌱 BASIC 등급 → 10% 할인
⚜️ GOLD → 20% 할인
💎 DIAMOND → 30% 할인
가장 먼저 떠올릴 수 있는 구현 방법은 String 을 사용하는 것이다.
1-1. String 사용
public int discount(String grade, int price) {
int discountPercent = 0;
if (grade.equals("BASIC")) {
discountPercent = 10;
} else if (grade.equals("GOLD")) {
discountPercent = 20;
} else if (grade.equals("DIAMOND")) {
discountPercent = 30;
} else {
System.out.println(grade + ": 할인 X");
}
return price * discountPercent / 100;
}
String 타입을 사용해서 매개변수로 grade 를 받은 후 equals 로 비교해서 할인 퍼센트를 리턴할 수 있도록 했다
하지만, 이 방식은 여러 가지 문제를 가진다.
- 존재하지 않는 등급을 입력한 경우 (VIP)
- 오타를 입력한 경우 (basiic)
- 소문자를 입력한 경우 (basic)
내가 원하는 방식대로 동작하지 않을 수 있다.
정리하자면 등급에 문자열을 사용하면 다음과 같은 문제가 발생할 수 있다
- 타입 안정성 부족 : 문자열은 오타가 발생하기 쉽다
- 데이터 일관성 떨어짐 : GOLD, gold, Gold 가 모두 같은 의미를 가지지만, String 은 정확히 일치해야지만 한다
- 값의 제한 부족 : 잘못된 문자열을 실수로 입력할 수 있지만 제한되지 않는다.
- 오류 발생 시 컴파일 오류 감지 불가 : 런타임에서 감지되기 때문에 오류 감지가 어렵다
1-2. 상수 사용
public class StringGrade {
public static final String BASIC = "BASIC";
public static final String GOLD = "GOLD";
public static final String DIAMOND = "DIAMOND";
}
위처럼 별도의 클래스를 만든 다음 상수들을 모아서 사용하면 위의 문제를 조금이나마 해결할 수 있는것처럼 보인다.
하지만, 파라미터로 String grade 를 받기 때문에 String 을 사용했을 때랑 같은 오류가 발생한다
2. 타입 안전 열거형 패턴
1번에서 발생한 문제를 해결하기 위해서는 타입 안전 열거형 패턴을 사용할 수 있다
public class ClassGrade {
public static final ClassGrade BASIC = new ClassGrade();
public static final ClassGrade GOLD = new ClassGrade();
public static final ClassGrade DIAMOND = new ClassGrade();
}
구현 방법
- 회원 등급을 다루는 ClassGrade 클래스를 만든다
- 회원 등급별로 ClassGrade 를 반환하는 클래스 상수 변수를 만든다 (static final)
- 각각의 상수마다 별도의 인스턴스를 생성하고 변수에 대입한다
그러면 회원 등급을 나타내는 타입 안전 열거형 패턴이 구현된다.
static final 을 사용해서 클래스 상수 변수로 만들었기 때문에 클래스.변수명 으로 사용할 수 있고,
매개변수로 ClassGrade 를 넘기고 인수로도 사용할 수 있다.
여기서 하나의 문제가 있다.
바로 객체를 직접 생성해서 외부에서 없는 등급을 직접 만들 수 있다는 점이다.
하지만, 이런 경우에는 ClassGrade 생성자를 private 로 만들어주면 문제가 해결된다
private ClassGrade() { }
장점
- 타입 안정성 향상 : 잘못된 값을 입력하는 문제를 근본적으로 방지한다
- 데이터 일관성 : 정해진 객체만 사용할 수 있다
- 제한된 인스턴스 생성 : 사전에 정의된 몇 개의 인스턴스만 생성한다
- 타입 안정성 : 잘못된 값이 할당되거나 사용되는 것을 컴파일 시점에 방지한다
→ String 과 상수를 썼을 때 발생했던 단점들을 모두 커버할 수 있다 !
단점
하지만, 이 패턴을 구현하려면 많은 코드를 작성해야하고
만약 깜박하고 private 생성자를 추가하지 않으면 타입 안전 열거형 패턴이 가지고 있는 장점들이 모두 깨진다
그렇기 떄문에 자바는 타입 안전 열거형을 쉽게 사용할 수 있도록 Enum Type 을 제공한다
3. 열거형 Enum Type
public enum Grade {
BASIC, GOLD, DIAMOND;
}
- 클래스 대신 enum 을 사용
- 원하는 상수의 이름을 나열
해주면 Enum 을 사용할 수 있다.
public class Grade extends Enum {
public static final ClassGrade BASIC = new ClassGrade();
public static final ClassGrade GOLD = new ClassGrade();
public static final ClassGrade DIAMOND = new ClassGrade();
// private 생성자 추가
private ClassGrade() {}
}
- enum 코드는 2번에서 살펴봤던 타입 안전 열거형 패턴 코드와 동일하게 동작한다.
- 열거형도 클래스로, 자동으로 java.lang.Enum 을 상속받는다
장점
- 타입 안정성 향상 : 유효하지 않은 값이 입력될 가능성이 없다
- 간결성 및 일관성 : 코드가 더 간결하고 명확해진다
- 확장성 : 새로운 회원 등급을 추가하고 싶으면, Enum 에 새로운 상수만 추가하면 된다
주요 메서드
| 메서드명 | 설명 |
| values() | 모든 enum 상수를 포함하는 배열을 반환 |
| valueOf(String name) | 주어진 이름과 일치하는 enum 상수를 반환 |
| name() | enum 상수의 이름을 문자열로 반환 |
| ordinal() | enum 상수의 선언 순서를 반환 (0부터 시작) |
| toString() | enum 상수의 이름을 문자열로 반환, 오버라이드 가능 |
🚨 ordinal() 주의사항
ordinal() 은 상수의 선언 순서를 반환한다.
하지만 가급적 !! 사용하지 않는게 좋다
위치가 고정되어 있는게 아니기 때문에 중간에 상수가 추가되거나 위치가 바뀌면 모든 위치가 변경될 수 있다
'🌱 인프런 > ☕️ 김영한의 실전 자바 - 중급 1편' 카테고리의 다른 글
| 자바 Object 클래스 (1) | 2025.09.01 |
|---|---|
| 자바 래퍼, Class 총정리 (0) | 2025.07.19 |
| 자바 예외처리 총정리 (1) | 2025.07.11 |
| 자바 중첩 클래스와 내부 클래스 (3) | 2025.07.09 |
| 자바 날짜와 시간 라이브러리 총정리 (0) | 2025.07.07 |