Enum

기본적으둜 cλ‚˜ c++의 enumκ³Ό 같은 κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” 클래슀둜 JDK 1.5이후에 생긴 ν΄λž˜μŠ€μ΄λ‹€.

cμ–Έμ–΄μ˜ C99 μ΄μ „μ—λŠ” booleanνƒ€μž…μ„ μ œκ³΅ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— λ‹€μŒκ³Ό 같이 μ‚¬μš©ν•˜κ³ λŠ” ν–ˆμ—ˆλ‹€.

typedef enum _boolean {
    FALSE,
    TRUE
} boolean;

#define FALSE 0
#define TRUE 1

Javaμ—μ„œμ˜ Enum νŠΉμ§•

Enum λΉ„κ΅μ‹œμ— 값이 μ•„λ‹Œ νƒ€μž…κΉŒμ§€λ„ 체크가 κ°€λŠ₯ν•˜κ³  Enum의 μƒμˆ˜κ°’μ΄ μž¬μ •μ˜ λ˜μ–΄λ„ λ‹€μ‹œ μ»΄νŒŒμΌν•˜μ§€ μ•ŠλŠ”λ‹€.

enum μ •μ˜ν•˜λŠ” 방법

enum Money { DOLLAR, WON, POUND, EURO, YEN, YUAN }

enum ν‚€μ›Œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ μ •μ˜λ₯Ό ν•  수 있고 μ •μ˜λ₯Ό 어디에 ν•˜λŠλƒμ— 따라 λΆ„λ₯˜λ₯Ό ν•΄λ³΄μžλ©΄ 3κ°€μ§€μ •λ„λ‘œ λΆ„λ₯˜ν•  수 μžˆλ‹€.

1. λ³„λ„μ˜ Java 파일둜 μ •μ˜

enum

2. 클래슀 μ•ˆμ— μ •μ˜

in

3. 클래슀 밖에 μ •μ˜

out

μ •μ˜ μœ„μΉ˜μ— 따라 enum객체가 μƒμ„±λœ μœ„μΉ˜κ°€ λ‹€λ₯Έ 것을 λ³Ό 수 μžˆλ‹€.

enum μ‚¬μš©

Money.DOLLAR와 같이 Enum이름.μƒμˆ˜λͺ…μœΌλ‘œ μ‚¬μš©μ„ ν•  수 있으며 Money money = Money.DOLLAR와 같이 λ³€μˆ˜μ— ν• λ‹Ή 해쀄 μˆ˜λ„ μžˆλ‹€.

C의 enum은 각 μƒμˆ˜κ°€ intν˜•μœΌλ‘œ μ €μž₯λ˜μ–΄ μ‚°μˆ μ—°μ‚°λ„ κ°€λŠ₯ν•˜κ³  μ•„λž˜μ™€ 같이 μƒμˆ˜λ¦¬ν„°λŸ΄κ³Ό 비ꡐ해도 κ°™κ²Œ λ‚˜μ˜€λŠ” λ¬Έμ œλ„ 생긴닀.

Enum이 없을 λ•Œ Javaμ—μ„œλ„ 이와 λΉ„μŠ·ν•˜κ²Œ class에 private final static intλ₯Ό μ΄μš©ν•΄μ„œ μƒμˆ˜κ°’μ„ μ •μ˜ ν•  수 μžˆμ—ˆλ‹€.

ν•˜μ§€λ§Œ 이 방법은 가독성에도 μ’‹μ§€ μ•Šκ³  λ³€μˆ˜λͺ…이 κ²ΉμΉ  수 μžˆκ±°λ‚˜ μƒμˆ˜λ¦¬ν„°λŸ΄κ³Ό 비ꡐ가 λœλ‹€λŠ” 문제점이 μžˆλ‹€.

Java의 Enum은 각 μƒμˆ˜κ°€ μƒμˆ˜ κ·Έ 자체둜써 μž‘λ™μ„ ν•˜κ³  μžλ£Œν˜•μ΄ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— μ•„λž˜μ™€ 같이 λΉ„κ΅ν•˜λ €κ³  ν•˜λ©΄ compile errorκ°€ λœ¬λ‹€.

μƒμˆ˜μ— λ‹€λ₯Έ κ°’ μΆ”κ°€

클래슀의 μƒμ„±μžμ™€ 같은 λ°©λ²•μœΌλ‘œ 값을 ν• λ‹Ή 해쀄 수 있으며, getterλ₯Ό μ •μ˜ν•΄μ„œ 값을 μ°Έμ‘° ν•  μˆ˜λ„ μžˆλ‹€.

μ΄λ•Œ μƒμ„±μžλŠ” PRIVATE μ†μ„±μœΌλ‘œ 생성해주어야 ν•œλ‹€.

enumνƒ€μž…μ€ κ³ μ •λœ μƒμˆ˜λ“€μ˜ μ§‘ν•©μ΄λ―€λ‘œ 컴파일 νƒ€μž„μ— λͺ¨λ“  값을 μ•Œκ³  μžˆμ–΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— λ‹€λ₯Έ ν΄λž˜μŠ€μ—μ„œ λ™μ μœΌλ‘œ 값을 정해쀄 수 μ—†κΈ° λ•Œλ¬Έμ— μƒμ„±μžλ₯Ό private둜 μ„€μ •ν•΄μ•Ό ν•˜κ³  finalκ³Ό 닀름이 μ—†μ–΄μ§„λ‹€.

enum이 μ œκ³΅ν•˜λŠ” λ©”μ†Œλ“œ

values()

Enum의 λͺ¨λ“  μƒμˆ˜λ₯Ό λ°°μ—΄λ‘œ λ§Œλ“€μ–΄ λ°˜ν™˜ν•΄μ£ΌλŠ” ν•¨μˆ˜

Money[]ν˜•νƒœμ˜ νƒ€μž…μœΌλ‘œ λ°˜ν™˜μ΄ λœλ‹€.

valuesOf()

λ§€κ°œλ³€μˆ˜λ‘œ Stringν˜•μ΄ 였며 이 λ§€κ°œλ³€μˆ˜μ™€ λ™μΌν•œ μ΄λ¦„μ˜ μƒμˆ˜λ₯Ό μ°Ύμ•„ μƒμˆ˜λ₯Ό λ°˜ν™˜ ν•˜κ³  μ—†λ‹€λ©΄ IllegalArgumentException μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚¨λ‹€.

ordianal()

enum μƒμˆ˜κ°€ 0λΆ€ν„° μ‹œμž‘ν•˜μ—¬ μ •μ˜λœ μˆœμ„œλ₯Ό λ°˜ν™˜(int)ν•˜λŠ” ν•¨μˆ˜

ordinal은 Enum을 μ •μ˜ν•œ μˆœμ„œλ₯Ό λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ— cλ•Œμ²˜λŸΌ μƒμˆ˜λΌκ³  μƒκ°ν•˜λ©° μ‚¬μš©ν•˜μ§€ 말자.

ordinal은 EnumSetμ΄λ‚˜ EnumMap, JPAμ—μ„œ μ ‘κ·Όν•˜κΈ° μœ„ν•œ λ‚΄λΆ€ ν•¨μˆ˜λ‘œ κ°œλ°œμžλŠ” 거의 μ‚¬μš©ν• μΌμ΄ μ—†λŠ” λ©”μ„œλ“œμ΄λ‹€.

μ •μ˜ μˆœμ„œκ°€ λ°”λ€Œκ±°λ‚˜ 값이 μΆ”κ°€ 되면 μ „ν˜€ λ‹€λ₯Έ κ²°κ³Όκ°€ λ‚˜μ˜€κΈ° λ•Œλ¬Έμ΄λ‹€.

그런 이유둜 Spring Data JPAμ—μ„œ defaultλŠ” ordinal이기 λ•Œλ¬Έμ— Enumμˆœμ„œκ°€ 바뀐닀면 값이 μ•„μ˜ˆ 달라진닀. 컬럼으둜 Enum을 μ‚¬μš©ν•˜λ©΄ @Enumeratedλ₯Ό μ΄μš©ν•΄ String으둜 μ‚¬μš©ν•˜μž.

java.lang.Enum

enum ν΄λž˜λŠ” 기본적으둜 java.lang.EnumλΌλŠ” λΆ€λͺ¨ 클래슀λ₯Ό 상속 λ°›κ³  있고 μ΄λŠ” Objectλ₯Ό 상속받고 Comparableκ³Ό Serializableλ₯Ό implementsν•˜κ³  μžˆλ‹€.

protectedν˜•μœΌλ‘œ μƒμ„±μžλ₯Ό ν•˜λ‚˜ κ°€μ§€κ³  μžˆλŠ”λ° μ΄λŠ” κ°œλ°œμžκ°€ ν˜ΈμΆœν•  수 μ—†κ³  μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ enum ν‚€μ›Œλ“œμ— λ°˜μ‘ν•˜μ—¬ μƒμ„±ν•˜κΈ° μœ„ν•¨μ΄λ‹€.

이 클래슀 내에 μžˆλŠ” public λ©”μ†Œλ“œ 쀑 Overrideν•΄μ„œ μ‚¬μš©ν• λ§Œν•œ λ©”μ„œλ“œλ‘œ 기본은 μƒμˆ˜ 이름을 λ°˜ν™˜ν•˜μ§€λ§Œ, enum을 μƒμ„±μ‹œ μΆ”κ°€ 값을 μ§€μ •ν•˜μ—¬ μƒμ„±ν–ˆλ‹€λ©΄ 이λ₯Ό Override해쀄 수 μžˆλ‹€.

컴파일 μ‹œμ˜ 객체 생성

enum ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ—΄κ±°ν˜•μ„ μƒμ„±ν•˜λ©΄ 컴파일 μ‹œμ— μœ„μ™€ 같이 μ •μ˜κ°€ λœλ‹€.

EnumSet

Set μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„

EnumSet은 abstractν‚€μ›Œλ“œκ°€ μ•žμ— λΆ™μ–΄ 객체 생성이 λΆˆκ°€λŠ₯ν•˜κ³  of()와 같은 좔상 νŒ©ν† λ¦¬ λ©”μ„œλ“œμ—μ„œ μ‚¬μš©ν•˜λŠ” noneOf(class<E> elementType) λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•˜μ—¬ 이λ₯Ό 톡해 κ΅¬ν˜„ 객체λ₯Ό 받을 수 μžˆλ‹€.

noneOf() λ©”μ„œλ“œλ₯Ό 보면 μ•Œκ² μ§€λ§Œ EnumSet 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 것이 μ•„λ‹Œ 이λ₯Ό 상속받은 ν΄λž˜μŠ€λ“€μ„ λ°˜ν™˜ν•˜κ³  μžˆλ‹€.

이 λ‘˜ 클래슀 λͺ¨λ‘ privateμ†μ„±μ΄λ―€λ‘œ 직접 μ‚¬μš©ν•  수 μ—†λ‹€.

  • μ‚¬μš©ν•  크기에 맞게 μ ν•©ν•œ κ΅¬ν˜„ 객체λ₯Ό 골라 μ€€λ‹€.

  • Enum의 μƒμˆ˜λ“€μ„ ν•˜λ‚˜ν•˜λ‚˜ Set에 λ‹΄λŠ” ν–‰μœ„λ₯Ό ν”Όν•  수 μžˆλ‹€.

  • EnumSet λ‚΄λΆ€ ν‘œν˜„μ€ λΉ„νŠΈ λ²‘ν„°λ‘œ ν‘œν˜„λœλ‹€. (μƒμˆ˜ κ°œμˆ˜κ°€ 64개 μ΄ν•˜λΌλ©΄ longλ³€μˆ˜ ν•˜λ‚˜λ‘œ ν‘œν˜„ν•œλ‹€.)

  • Enum μƒμˆ˜κ°€ μ„ μ–Έλœ μˆœμ„œ, 즉 ordinal() λ©”μ„œλ“œμ˜ λ°˜ν™˜λœ μˆœμ„œλ‘œ μˆœνšŒν•œλ‹€.

  • EnumSet iteratorλŠ” μ•½ν•œ 일관성을 μœ μ§€ν•˜μ—¬ ConcurrentModificationException을 λ°œμƒμ‹œν‚€μ§€ μ•ŠλŠ”λ‹€.

  • null μš”μ†ŒλŠ” μ‚½μž…μ΄ λ˜μ§€ μ•ŠλŠ”λ‹€.

  • 동기화가 λ˜μ§€ μ•ŠλŠ”λ‹€.

λ©”μ„œλ“œ

  • EnumSet.allOf(Class elementType) : λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…μ˜ λͺ¨λ“  μš”μ†Œλ₯Ό ν¬ν•¨ν•œ EnumSet을 λ°˜ν™˜

  • EnumSet.noneOf(Class elementType) : λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…μ˜ λΉ„μ–΄μžˆλŠ” EnumSetλ°˜ν™˜

  • EnumSet.of(E e1, E e2 ...) : μ§€μ •ν•œ λ§€κ°œλ³€μˆ˜λ₯Ό ν¬ν•¨ν•œ EnumSet을 λ°˜ν™˜

  • κ·Έ μ™Έ java.util.AbstractSet, java.util.AbstractCollection, java.lang.Object, java.util.Set으둜 λΆ€ν„° λ©”μ„œλ“œλ“€μ„ 상속받고 μžˆλ‹€.

    • 쀑볡 검사λ₯Ό μœ„ν•œ equals(),hashCode() ,add(),remove(),size(), toArray() => Object[] λ°˜ν™˜, iterator()λ“± μ‚¬μš© κ°€λŠ₯

EnumMap

Map μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„

  • Enum을 Key둜 μ΄μš©ν•˜λŠ” Map이닀.

  • Enum μƒμˆ˜λ‘œ null을 갖을 수 μ—†κΈ° λ•Œλ¬Έμ— null을 key둜 κ°–μ§€ λͺ»ν•œλ‹€.

  • Enum은 μ •ν•΄μ§„ μƒμˆ˜λ₯Ό μ‚¬μš©ν•˜κ³  단일 객체이기 λ•Œλ¬Έμ— ν•΄μ‹±ν•˜μ§€ μ•Šκ³  이미 μˆœμ„œκ°€ μ •ν•΄μ Έμžˆμ–΄ μ„±λŠ₯이 μ’‹λ‹€.

  • key와 valueκ°€ λ°°μ—΄λ‘œ κ΅¬μ„±λ˜μ–΄μžˆλ‹€.

  • EnumMap의 keyλŠ” ordianl둜 관리 되기 λ•Œλ¬Έμ— iteratorλŠ” μ•½ν•œ 일관성을 μœ μ§€ν•˜μ—¬ ConcurrentModificationException을 λ°œμƒμ‹œν‚€μ§€ μ•ŠλŠ”λ‹€.

  • 동기화가 λ˜μ§€ μ•ŠλŠ”λ‹€.

λ©”μ„œλ“œ

  • μƒμ„±μž : newν‚€μ›Œλ“œλ₯Ό μ΄μš©ν•΄ 생성할 수 있고 일반 Mapλ“€κ³Ό λ‹€λ₯΄κ²Œ enum νƒ€μž…μ„ νŒŒλΌλ―Έν„°λ‘œ λ„˜κ²¨μ£Όμ–΄μ•Ό ν•œλ‹€.

    • Map<Money,Integer> map = new EnumMap<>(Money.class);

  • clear() : λͺ¨λ“  μš”μ†Œ μ‚­μ œ

  • get(Object key) : key에 ν•΄λ‹Ήν•˜λŠ” value 리턴

  • put(K key, V value) : map에 데이터 μž…λ ₯

  • remove(Object key) : ν•΄λ‹Ήν•˜λŠ” keyκ°€ μžˆλ‹€λ©΄ μ‚­μ œ

  • equals(Object object) : κΈ°μ€€ Mapκ³Ό 같은지 비ꡐ

  • containsKey(Object key) / containsValue(Object value) : ν•΄λ‹Ήν•˜λŠ” key와 value κ°€ μžˆλ‹€λ©΄ true λ°˜ν™˜

  • size() : Map의 μš”μ†Œ 개수 λ°˜ν™˜

  • keySet() : Map에 μžˆλŠ” λͺ¨λ“  keyλ“€μ˜ Set viewλ₯Ό λ°˜ν™˜ν•œλ‹€. (λͺ¨λ“  key듀을 보여쀀닀.)

  • values() : Map에 μžˆλŠ” valueλ“€μ˜ Collection viewλ₯Ό λ°˜ν™˜ν•œλ‹€. (λͺ¨λ“  값듀을 보여쀀닀.)

μΆ”κ°€ λ‚΄μš©

type safety

Runtime이 μ•„λ‹Œ Complieνƒ€μž„μ— 문제λ₯Ό μž‘μ„ 수 μžˆλŠ” κ²ƒμœΌλ‘œ JVM은 μ»΄νŒŒμΌν• λ•Œ, νŠΉμ • 데이터 νƒ€μž…μ„ μ•Œ 수 μžˆμœΌλ‚˜ RUNμ‹œμ— νŠΉμ • 데이터가 쑴재 ν•˜μ§€ μ•ŠλŠ”λ‹€κ±°λ‚˜ ν•˜λŠ” λ¬Έμ œκ°€ 생길 수 μžˆλ‹€.

Enum을 μ‚¬μš©ν•˜λ©΄ μ˜€νƒ€λ°©μ§€λ₯Ό ν•  수 있고, μ»΄νŒŒμΌνƒ€μž„μ— μ—λŸ¬λ₯Ό μž‘μ•„μ£ΌκΈ° λ•Œλ¬Έμ— 디버깅도 μ‰¬μ›Œμ§„λ‹€.

Enumμ—μ„œ κ°’ μ…‹νŒ… 팁

Enum의 값을 좔가해쀄 λ•Œ 1,2,3같이 쒁은 숫자의 λ²”μœ„κ°€ μ•„λ‹Œ 10,20,30 같이 λ²”μœ„λ₯Ό 두고 μ„ μ–Έν•΄μ£Όμž.

μ–Έμ œ μ–΄λ–€μ΄μœ μ—μ„œ Enum에 값을 사이에 μΆ”κ°€ 해쀄지 λͺ¨λ₯΄κΈ° λ•Œλ¬Έμ΄λ‹€.


Reference

https://www.nextree.co.kr/p11686/

http://cris.joongbu.ac.kr/course/java/api/java/lang/Enum.html

https://javarevisited.blogspot.com/2014/03/how-to-use-enumset-in-java-with-example.html#axzz6kSbFjAwM

Last updated