Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 27 | 28 | 29 | 30 | 31 |
Tags
- Spring
- java
- MySQL
- LifeCycle
- typescript
- winston
- nestjs
- JWT
- Kubernetes
- 알고리즘
- GraphQL
- Linux
- 코딩테스트
- node.js
- dfs
- 인접리스트
- javascript
- Interceptor
- OOP
- REST API
- 탐욕법
- 자료구조
- css
- 프로그래머스
- 인접행렬
- TIL
- html
- Deep Dive
- bean
- puppeteer
Archives
- Today
- Total
처음부터 차근차근
[Java] Enum 본문
728x90
Enum Type
enum은 Enumeration의 줄임말로, 번역하면 열겨라는 뜻이다.
enum은 일련의 명명된 상수들의 집합을 정의하는 것을 의미하며, 프로그래밍에서는 이러한 상수들을 사용하여 코드 내에서 미리 정의된 값들의 집합을 나타낸다.
Enum은 왜 만들어졌을까??
Enum은 타입 안전 열거형 패턴(Type-Safe Enum Pattern)으로부터 만들어졌다.
간단한 예시로, 특정 문자열을 사용해서 회원을 구분하는 경우, 아래와 같은 문제점이 발생할 수 있다.
- 문자열은 오타가 발생하기 쉽고, 유효하지 않은 값이 입력될 수 있다.
- "Gold", "gold" 등 다양한 형식으로 문자열을 입력할 수 있다.
이러한 문제를 해결하기 위해 특정 범위로 값을 제한할려고 하였으며, 나열한 항목만 사용할 수 있도록 아래 예시와 같은 코드가 만들어졌다.
public class ClassGrade {
public static final ClassGrade BASIC = new ClassGrade();
public static final ClassGrade GOLD = new ClassGrade();
public static final ClassGrade DIAMOND = new ClassGrade();
// private 생성자 추가 -> 객체를 생성하지 못하도록 막는다.
private ClassGrade() {}
}
이렇게 타입 안전 열거형 패턴을 만든다면
- 타입 안정성 향상: 정해진 객체만 사용할 수 있기 때문에, 잘못된 값을 입력하는 문제를 근본적으로 방지할 수 있다.
- 데이터 일관성: 정해진 객체만 사용하므로 데이터의 일관성이 보장된다.
- 제한된 인스턴스 생성: 클래스는 사전에 정의된 몇 개의 인스턴스만 생성하고, 외부에서는 이 인스턴스들만 사용할 수 있도록 한다. 이를 통해 미리 정의된 값들만 사용하도록 보장한다.
- 타입 안전성: 이 패턴을 사용하면, 잘못된 값이 할당되거나 사용되는 것을 컴파일 시점에 방지할 수 있다. 예를 들어, 특정 메서드가 특정 열거형 타입의 값을 요구한다면, 오직 그 타입의 인스턴스만 전달할 수 있다. 여기서는 메서드의 매개변수로
ClassGrade
를 사용하는 경우, 앞서 열거한BASIC
,GOLD
,DIAMOND
만 사용할 수 있다.
단, 이러한 패턴을 구현하려면 코드를 많이 작성해야 한다. 따라서 Java에서는 편하게 사용할 수 있도록 Enum이라는 타입을 만들어줬다.
package enumeration.ex3;
public enum Grade {
BASIC, GOLD, DIAMOND
}
타입 안전 열거형 패턴보다 오히려 더 간단하게 만들 수 있다.
Enum의 특징
- 열거형도 Class이다.
- 열거형은 자동으로 java.lang.Enum을 상속 받는다.
- 외부에서 임의로 생성할 수 없다.
간단하게 Enum을 실행시켜보자.
public class EnumRefMain {
public static void main(String[] args) {
System.out.println("class BASIC = " + Grade.BASIC.getClass());
System.out.println("class GOLD = " + Grade.GOLD.getClass());
System.out.println("class DIAMOND = " + Grade.DIAMOND.getClass());
System.out.println("ref BASIC = " + refValue(Grade.BASIC));
System.out.println("ref GOLD = " + refValue(Grade.GOLD));
System.out.println("ref DIAMOND = " + refValue(Grade.DIAMOND));
}
private static String refValue(Object grade) {
return Integer.toHexString(System.identityHashCode(grade));
}
}
실행결과
class BASIC = class enumeration.ex3.Grade
class GOLD = class enumeration.ex3.Grade
class DIAMOND = class enumeration.ex3.Grade
ref BASIC = x001
ref GOLD = x002
ref DIAMOND = x003
실행 결과를 보면 상수들이 열거형으로 선언한 타입인 Grade
타입을 사용하는 것을 확인할 수 있다. 그리고 각각의 인스턴스도 서로 다른 것을 확인할 수 있다.
참고로 열거형은 toString()
을 재정의 하기 때문에 참조값을 직접 확인할 수 없다. 참조값을 구하기 위해 refValue()
를 만들었다.
System.identityHashCode(grade)
: 자바가 관리하는 객체의 참조값을 숫자로 반환한다.Integer.toHexString()
: 숫자를 16진수로 변환, 우리가 일반적으로 확인하는 참조값은 16진수
열거형도 클래스이다. 열거형을 제공하기 위해 제약이 추가된 클래스라 생각하면 된다.
Enum의 장점
- 타입 안정성 향상: 열거형은 사전에 정의된 상수들로만 구성되므로, 유효하지 않은 값이 입력될 가능성이 없다. 이런 경우 컴파일 오류가 발생한다.
- 간결성 및 일관성: 열거형을 사용하면 코드가 더 간결하고 명확해지며, 데이터의 일관성이 보장된다.
- 확장성: 새로운 회원 등급을 타입을 추가하고 싶을 때, ENUM에 새로운 상수를 추가하기만 하면 된다.
Enum 주요 메서드
- values(): 모든 ENUM 상수를 포함하는 배열을 반환한다.
- valueOf(String name): 주어진 이름과 일치하는 ENUM 상수를 반환한다.
- name(): ENUM 상수의 이름을 문자열로 반환한다.
- ordinal(): ENUM 상수의 선언 순서(0부터 시작)를 반환한다.
- toString(): ENUM 상수의 이름을 문자열로 반환한다.
name()
메서드와 유사하지만,toString()
은 직접 오버라이드 할 수 있다.
참고로, ordinal()
의 값은 가급적 사용하지 않는 것이 좋다. 왜냐하면 이 값을 사용하다가 중간에 상수를 선언하는 위치가 변경되면 전체 상수의 위치가 모두 변경될 수 있기 때문이다.
Enum 예시 코드
public enum Grade {
BASIC(10), GOLD(20), DIAMOND(30);
// class처럼 내부 맴버를 가질 수 있다.
private final int discountPercent;
// 또한 생성자도 사용이 가능하다.
// 단, 생성자에 접근이 불가능하도록 막혀있다. private이라고 생각하면 편하다.
Grade(int discountPercent) {
this.discountPercent = discountPercent;
}
// 메서드도 가질 수 있다.
public int getDiscountPrecent() {
return discountPercent;
}
public int discount(int price) {
return price * discountPercent / 100;
}
}
참조
'Language > Java' 카테고리의 다른 글
[Java] 날짜와 시간 (4) | 2024.08.27 |
---|---|
[Java] Wrapper Class (0) | 2024.07.31 |
[Java] String 클래스 (0) | 2024.07.31 |
[Java] 불변 객체 (0) | 2024.07.26 |
[Java] Object 클래스 (0) | 2024.07.24 |