Language/Java

β˜• μžλ°” Enum μ—΄κ±°ν˜• νƒ€μž… 문법 & μ‘μš© πŸ’― 정리

인파_ 2022. 12. 6. 07:41

java-enum

Enum μ—΄κ±° νƒ€μž… 

λ¨Όμ € Enum은 "Enumeration"의 μ•½μžλ‹€. Enumeration은 "μ—΄κ±°, λͺ©λ‘, μΌλžŒν‘œ" λΌλŠ” λœ»μ„ κ°€μ§€κ³  μžˆμœΌλ©°, λ³΄ν†΅ ν•œκΈ€λ‘œλŠ” μ—΄κ±°ν˜•μ΄λΌκ³  λΆ€λ₯Έλ‹€. μ¦‰, μ—΄κ±°ν˜•(enum)은 μš”μ†Œ, λ©€λ²„라 λΆˆλ¦¬λŠ” λͺ…λͺ…λœ κ°’μ˜ μ§‘합을 μ΄λ£¨λŠ” μžλ£Œν˜•μ΄λ‹€. μ–΄λ ΅κ²Œ μƒκ°ν•  ν•„μš” μ—†μ΄ μƒμˆ˜ λ°μ΄ν„°λ“€μ˜ μ§‘ν•© μœΌλ‘œ μΉ˜λΆ€ν•˜λ©΄ λœλ‹€.

 

λ¨Όμ € Enum은 "Enumeration"의 μ•½μžλ‹€. 

Enumerationμ€ν”„λ‘œκ·Έλž˜λ°μ„ ν•˜λ‹€λ³΄λ©΄ λ°°μ—΄μ΄λ‚˜ λ¦¬μŠ€νŠΈ ..λ“± μ—¬λŸ¬κ°œμ˜ λ¬ΆμŒ λ°μ΄ν„°λ₯Ό λ‹€λ£¨λŠ” μΌμ΄ λΉˆλ²ˆν•˜λ‹€. μ΄ λ¬ΆμŒ λ°μ΄ν„° μ€‘μ—λŠ” λ°μ΄ν„° μ£Όμ œμ— λ”°λΌ λͺ‡κ°€μ§€λ‘œ ν•œμ •λœ κ°’λ§Œμ„ κ°€μ§€λŠ” κ²½μš°κ°€ μ‘΄μž¬ν•œλ‹€. 

λŒ€ν‘œμ μœΌλ‘œλŠ” 'μš”μΌ' μ΄λ‚˜ 'κ³„μ ˆ' λ˜λŠ” 'μ£Όμ‚¬μœ„' κ°™μ€ μ˜ˆμ œλ₯Ό λ“€ μˆ˜ μžˆλ‹€. μš”일은 μ›”,ν™”,수,λͺ©,금,ν† ,일 μ΄λ ‡κ²Œ 7가지 λ°–에 μ—†κ³ , κ³„μ ˆλ„ λ΄„,여름,가을,겨울 4가지 κ³„μ ˆλ‘œ ν•œμ •λ˜μ–΄ μžˆμœΌλ©°, μ£Όμ‚¬μœ„λŠ” 1,2,3,4,5,6 μˆ«μžκ°€ 6개둜만 κ΅¬μ„±λ˜μ–΄ μžˆλ‹€. 

이와 κ°™μ΄ μ •ν•΄μ Έ μžˆλŠ” ν•œμ •λœ λ°μ΄ν„° λ¬ΆμŒμ„ μ—΄κ±°ν˜• νƒ€μž…인 Enum μœΌλ‘œ λ¬Άμ–΄μ£Όλ©΄ λ³΄λ‹€ κ΅¬μ‘°μ μœΌλ‘œ ν”„λ‘œκ·Έλž˜λ° ν•  μˆ˜ μžˆλ‹€.


κ³Όκ±°μ—” μƒμˆ˜λ₯Ό μ–΄λ–»κ²Œ μ •μ˜ν–ˆλŠ”κ°€?

 

final μƒμˆ˜

κ°€μž₯ λ¨Όμ € λ– μ˜€λ₯΄λŠ” 것은 final μ œμ–΄μžλ₯Ό μ΄μš©ν•΄ λ³€μˆ˜λ₯Ό μƒμˆ˜ν™” ν•˜λŠ” 것일 것이닀. 

final μ œμ–΄μžλ₯Ό ν• λ‹Ήν•¨μœΌλ‘œμ¨μ„ μ‚¬μš©ν•˜μ—¬ ν•œλ²ˆ μ§€μ •ν•˜λ©΄ λ°”λ€Œμ§€ μ•Šκ²Œ μ„€μ •λ˜λ©°, λ™μ‹œμ— static을 μ‚¬μš©ν•˜μ—¬ λ©”λͺ¨λ¦¬μ— ν•œ 번만 ν• λ‹Ή 되게 μ„€μ •λœλ‹€. ν•˜μ§€λ§Œ 이 방법은 μ ‘κ·Όμ œμ–΄μžλ“€ λ•Œλ¬Έμ— 가독성이 κ·Έλ ‡κ²Œ 쒋지 λͺ»ν•˜λ‹€λΌλŠ” 단점이 μ‘΄μž¬ν•œλ‹€.

class EnumExample {
    private final static int MONDAY = 1;
    private final static int TUESDAY = 2;
    private final static int WEDNESDAY = 3;
    private final static int THURSDAY = 4;
    private final static int FRIDAY = 5;
    private final static int SATURDAY = 6;
    private final static int SUNDAY = 7;
    
    public static void main(String[] args) {

        int day = EnumExample.MONDAY;

        switch (day) {
            case EnumExample.MONDAY:
                System.out.println("μ›”μš”μΌ μž…λ‹ˆλ‹€.");
                break;
            case EnumExample.TUESDAY:
                System.out.println("ν™”μš”μΌ μž…λ‹ˆλ‹€.");
                break;
            case EnumExample.WEDNESDAY:
                System.out.println("μˆ˜μš”μΌ μž…λ‹ˆλ‹€.");
                break;
        }
    }
}

java-enum

 

μΈν„°νŽ˜μ΄μŠ€ μƒμˆ˜

interfaceλŠ” λ°˜λ“œμ‹œ 좔상 λ©”μ†Œλ“œλ§Œ μ„ μ–Έν•  수 μžˆλŠ” 것이 μ•„λ‹ˆλ‹€. μΈν„°νŽ˜μ΄μŠ€ λ‚΄μ—μ„œλ„ μƒμˆ˜λ₯Ό μ„ μ–Έν•  수 μžˆλŠ”λ°, μΈν„°νŽ˜μ΄μŠ€μ˜ λ©€λ²„λŠ” public static final 속성을 μƒλž΅ν•  수 μžˆλŠ” νŠΉμ§•μ„ μ΄μš©ν•˜μ—¬ μ½”λ“œλ₯Ό 쑰금 더 κ°„κ²°ν•˜κ²Œ μž‘μ„±ν•  수 있게 λœλ‹€.

interface DAY {
    int MONDAY = 1;
    int TUESDAY = 2;
    int WEDNESDAY = 3;
    int THURSDAY = 4;
    int FRIDAY = 5;
    int SATURDAY = 6;
    int SUNDAY = 7;
}

interface MONTH {
    int JANUARY = 1;
    int FEBRUARY = 2;
    int MARCH = 3;
    int APRIL = 4;
    int MAY = 5;
    int JUNE = 6;
    int JULY = 7;
    int AUGUST = 8;
    int SEPTEMBER = 9;
    int OCTOBER = 10;
    int NOVEMBER = 11;
    int DECEMBER = 12;
}

ν•˜μ§€λ§Œ μΈν„°νŽ˜μ΄μŠ€λ‘œ μƒμˆ˜λ₯Ό μ •μ˜ν•˜λŠ” 방법에도 λ¬Έμ œκ°€ μžˆλ‹€.

쑰금 원둠적인 문제이긴 ν•œλ°, μƒμˆ˜κ°€ 결ꡭ은 μ •μˆ˜κ°’μ΄λΌλŠ” λ¬Έμ œμ΄λ‹€. μƒμˆ˜λŠ” 'λ³€ν•˜μ§€ μ•ŠλŠ” κ°’'μ΄λΌλŠ” μ˜λ―Έμ΄μ§€λ§Œ 'κ³ μœ ν•œ κ°’' μ΄λΌλŠ” μ˜λ―Έλ„ μ–΄λŠμ •λ„ λ‚΄ν¬ν•˜κ³  μžˆλ‹€.

κ·Έλž˜μ„œ μ•„λž˜ μ½”λ“œ 처럼 λ‹€λ₯Έ 집합에 μ •μ˜λœ μƒμˆ˜λ“€ 끼리 μ„œλ‘œ λΉ„κ΅ν•˜λŠ” 둜직이 κ°€λŠ₯ν•˜κ±°λ‚˜, 잘λͺ»λœ μƒμˆ˜κ°€ ν• λ‹Ήλ˜μ—ˆμŒμ—λ„ 결ꡭ은 μ •μˆ˜κ°’μ΄κΈ° λ•Œλ¬Έμ— 컴파일 μ—λŸ¬μ—†μ΄ μ‹€ν–‰λœλ‹€λŠ” 점이닀. 이것이 무엇이 λ¬Έμ œλƒ μΌμˆ˜λ„ μžˆκ² μ§€λ§Œ ν”„λ‘œκ·Έλž¨ 크기가 컀질수둝 개발자의 μ‹€μˆ˜κ°€ μž¦μ•„μ§€λ©° μ΄λŸ¬ν•œ μ œμ•½μ μ΄μ§€ μ•ŠλŠ” μš”μ†Œλ“€ λ•Œλ¬Έμ— ν”„λ‘œκ·Έλž¨μ— 버그가 λ°œμƒν•˜κ²Œ λ˜λŠ” 것이닀.

public static void main(String[] args) {

    int day = DAY.MONDAY;

    // μƒμˆ˜λ₯Ό λΉ„κ΅ν•˜λŠ” λ…Όλ¦¬μ μœΌλ‘œ 잘λͺ»λœ ν–‰μœ„λ₯Ό ν•¨μœΌλ‘œμ¨ day λ³€μˆ˜μ— λ‹€λ₯Έ μƒμˆ˜κ°’μ΄ 듀어가버림
    if (DAY.MONDAY == MONTH.JANUARY) {
        // ...
        day = MONTH.JANUARY;
    }

    // day λ³€μˆ˜μ— μžˆλŠ” μƒμˆ˜λŠ” MONTH μƒμˆ˜μ΄κΈ° λ•Œλ¬Έμ— μ‘°κ±΄λ¬Έμ—μ„œ κ±ΈλŸ¬μ Έμ•Ό λ˜μ§€λ§Œ,
    // κ²°κ΅­ μ •μˆ˜κ°’μ΄κΈ° λ•Œλ¬Έμ— μ—λŸ¬κ°€ μ•ˆλ‚˜κ³  κ·ΈλŒ€λ‘œ μˆ˜ν–‰λ¨ -> ν”„λ‘œκ·Έλž¨ 버그 λ°œμƒ κ°€λŠ₯μ„±
    switch (day) {
        case DAY.MONDAY:
            System.out.println("μ›”μš”μΌ μž…λ‹ˆλ‹€.");
            break;
        case DAY.TUESDAY:
            System.out.println("ν™”μš”μΌ μž…λ‹ˆλ‹€.");
            break;
        case DAY.WEDNESDAY:
            System.out.println("μˆ˜μš”μΌ μž…λ‹ˆλ‹€.");
            break;
    }
}

java-enum

 

자체 클래슀 μƒμˆ˜

λ”°λΌμ„œ μƒμˆ˜λ₯Ό μ •μˆ˜κ°’μœΌλ‘œ κ΅¬μ„±ν•˜λŠ” 것이 μ•„λ‹ˆλΌ λ…λ¦½λœ 고유의 객체둜 μ„ μ–Έν•˜μžλŠ” μ·¨μ§€λ‘œ 자체 클래슀 μΈμŠ€ν„΄μŠ€ν™”λ₯Ό μ΄μš©ν•΄ μƒμˆ˜μ²˜λŸΌ μ‚¬μš©ν•˜λŠ” 기법이 λ“±μž₯ν•˜μ˜€λ‹€.

자기 μžμ‹  객체λ₯Ό μΈμŠ€ν„΄μŠ€ν™” ν•˜κ³  final static ν™” ν•¨μœΌλ‘œμ¨ 고유의 객체λ₯Ό μ–»κ²Œλ˜μ–΄ 이λ₯Ό μƒμˆ˜μ²˜λŸΌ ν™œμš©ν•˜λŠ” 것이닀.

class Day {
    // 자기 μžμ‹  객체λ₯Ό μΈμŠ€ν„΄μŠ€ν™” ν•˜κ³  final static ν™” ν•¨μœΌλ‘œμ¨ 고유의 객체 μƒμˆ˜λ₯Ό μ–»κ²Œ 됨
    public final static Day MONDAY = new Day();
    public final static Day TUESDAY = new Day();
    public final static Day WEDNESDAY = new Day();
}

class Month {
    public final static Month JANUARY = new Month();
    public final static Month FEBRUARY = new Month();
    public final static Month MARCH = new Month();
}

ν•˜μ§€λ§Œ 가독성이 λ‹€μ‹œ μ•ˆμ’‹μ•„μ‘Œκ³ , 무엇보닀 μ΄λŸ¬ν•œ 방식은 ifλ¬Έμ—μ„œλŠ” λ¬Έμ œλŠ” μ—†μ§€λ§Œ switchλ¬Έμ—μ„œ μ‚¬μš©ν• μˆ˜ μ—†λ‹€λŠ” 큰 단점이 μžˆλ‹€. κ·Έ μ΄μœ λŠ” switch 문의 쑰건에 λ“€μ–΄κ°€λŠ” 데이터 νƒ€μž…μ΄ μ œν•œμ μ΄κΈ° λ•Œλ¬Έμ΄λ‹€.

public static void main(String[] args) {

    Day day = Day.MONDAY;

    // if문은 문제 μ—†μ§€λ§Œ
    if(day == Day.MONDAY) {
        System.out.println("μ›”μš”μΌ μž…λ‹ˆλ‹€.");
    }

    // switchλ¬Έμ—μ„œλŠ” μ‚¬μš©ν• μˆ˜ μ—†λ‹€
    switch (day) {
        case DAY.MONDAY:
            System.out.println("μ›”μš”μΌ μž…λ‹ˆλ‹€.");
            break;
        case DAY.TUESDAY:
            System.out.println("ν™”μš”μΌ μž…λ‹ˆλ‹€.");
            break;
        case DAY.WEDNESDAY:
            System.out.println("μˆ˜μš”μΌ μž…λ‹ˆλ‹€.");
            break;
    }
}

java-enum
java-enum

 

enum μƒμˆ˜

μ΄λŸ¬ν•œ λ¬Έμ œλ“€ λ•Œλ¬Έμ— μžλ°”μ—μ„œλŠ” μ•„μ˜ˆ μƒμˆ˜λ§Œμ„ λ‹€λ£¨λŠ” enum νƒ€μž… 클래슀λ₯Ό λ§Œλ“€μ–΄ λ°°ν¬ν•œ 것이닀.

μœ„μ˜ μƒμˆ˜ μ½”λ“œλ₯Ό enum 으둜 바꿔보면 λ‹€μŒκ³Ό κ°™λ‹€.

enum Day{
	MONDAY,TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

enum Month{
	JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, 
	AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER;
}

enum의 핡심은 μ΄λŸ¬ν•œ μƒμˆ˜λ₯Ό λ‹¨μˆœνžˆ μ •μˆ˜λ‘œ μΉ˜λΆ€ν•˜μ§€λ§κ³  객체 지ν–₯적으둜 κ°μ²΄ν™”ν•΄μ„œ κ΄€λ¦¬ν•˜μžλŠ” 취지이닀.

예λ₯Όλ“€μ–΄ Cμ–Έμ–΄μ˜ enum은 κ·Έλƒ₯ μ •μˆ˜μ΄λ©°, C++의 enum은 νƒ€μž…μ΄μ§€λ§Œ, JAVA의 enum은 μΈν„°νŽ˜μ΄μŠ€μ™€ 같이 λ…λ¦½λœ νŠΉμˆ˜ν•œ 클래슀둜 κ΅¬λΆ„ν•œλ‹€. 즉, μΌμ’…μ˜ 객체이기 λ•Œλ¬Έμ— νž™(heap) λ©”λͺ¨λ¦¬μ— μ €μž₯되며 각 enum μƒμˆ˜λ“€μ€ λ³„κ°œμ˜ λ©”λͺ¨λ¦¬ μ£Όμ†Œκ°’μ„ κ°€μ§μœΌλ‘œμ¨ μ™„λ²½νžˆ λ…λ¦½λœ μƒμˆ˜λ₯Ό ꡬ성할 수 μžˆλŠ” 것이닀.

λ˜ν•œ IDEμ—μ„œ 클래슀 νŒŒμΌμ„ μƒμ„±ν• λ•Œ λ…λ¦½λœ μ—΄κ±°ν˜• νŒŒμΌλ„ 생성할 수 μžˆλ‹€. (λ…λ¦½λœ 클래슀이기 λ•Œλ¬Έμ—)

java-enum
IntelliJ 파일 생성 ν™”λ©΄


Enum의 μž₯점

  • μ½”λ“œκ°€ λ‹¨μˆœν•΄μ§€λ©° 가독성이 쒋아진닀
  • ν—ˆμš© κ°€λŠ₯ν•œ 값듀을 μ œν•œν•˜μ—¬ μœ ν˜• μ•ˆμ „(type safe)을 μ œκ³΅ν•œλ‹€.
  • ν‚€μ›Œλ“œ enum을 μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— κ΅¬ν˜„μ˜ μ˜λ„κ°€ μ—΄κ±°μž„μ„ λΆ„λͺ…ν•˜κ²Œ λ‚˜νƒ€λ‚Ό 수 μžˆλ‹€.
  • 자체 클래슀 μƒμˆ˜μ™€ 달리 switchλ¬Έμ—μ„œλ„ μ‚¬μš©ν•  수 μžˆλ‹€
  • λ‹¨μˆœ μƒμˆ˜μ™€ 비ꡐ해 IDE의 적극적인 지원을 받을 수 μžˆλ‹€ (μžλ™μ™„μ„±, μ˜€νƒ€κ²€μ¦, ν…μŠ€νŠΈ λ¦¬νŒ©ν† λ§ λ“±λ“±)
  • λ¦¬νŒ©ν† λ§μ‹œ λ³€κ²½ λ²”μœ„κ°€ μ΅œμ†Œν™” λœλ‹€ (enumμ—μ„œ ν•œλ²ˆμ— κ΄€λ¦¬ν•˜κΈ° λ•Œλ¬Έμ— λ‚΄μš©μ˜ μΆ”κ°€κ°€ ν•„μš”ν•˜λ”λΌλ„, Enum μ½”λ“œμ™Έμ— μˆ˜μ •ν•  ν•„μš”κ°€ μ—†λ‹€)
  • enum은 본질적으둜 Thread safe인 싱글톀 객체 μ΄λ―€λ‘œ 싱글톀 클래슀λ₯Ό μƒμ„±ν•˜λŠ”λ°μ—λ„ μ‚¬μš©λœλ‹€

μΆ”κ°€μ μœΌλ‘œ enum μ„±λŠ₯은 μ–΄λ–¨κ°€ μ‹Άμ§€λ§Œ, μ •μˆ˜ μƒμˆ˜μ™€ λ‹€λ₯΄μ§€ μ•ŠμœΌλ©° μ—΄κ±° νƒ€μž…μ„ λ©”λͺ¨λ¦¬μ— μ˜¬λ¦¬λŠ” 곡간과 μ΄ˆκΈ°ν™” μ‹œκ°„μ΄ μžˆμ§€λ§Œ 체감될 μ •λ„λŠ” μ•„λ‹ˆλ‹€.


Enum κΈ°λ³Έ 문법

 

Enum μ„ μ–Έ

μ—΄κ±° νƒ€μž…μ€ μƒμˆ˜ λ°μ΄ν„°λ“€μ˜ 집합이라고 ν•˜μ˜€λ‹€. λ”°λΌμ„œ μ•„λž˜μ™€ 같이 마치 λ°°μ—΄ 처럼 λ‚˜μ—΄ν•˜μ—¬ ν‘œν˜„ν•˜λ©΄ λœλ‹€.

  • enum λͺ…은 ν΄λž˜μŠ€μ™€ 같이 첫 문자λ₯Ό λŒ€λ¬Έμžλ‘œν•˜κ³  λ‚˜λ¨Έμ§€λŠ” μ†Œλ¬Έμžλ‘œ κ΅¬μ„±ν•œλ‹€
  • κ΄€λ‘€μ μœΌλ‘œ, μ—΄κ±° μƒμˆ˜λŠ” λͺ¨λ‘ λŒ€λ¬Έμžλ‘œ μž‘μ„±ν•œλ‹€
  • μ—΄κ±° μƒμˆ˜κ°€ μ—¬λŸ¬ λ‹¨μ–΄λ‘œ ꡬ성될 경우, 단어 사이λ₯Ό 밑쀄 (_)둜 μ—°κ²°ν•œλ‹€
// μš”μΌ μ—΄κ±° νƒ€μž…
enum Week {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}
// κ³„μ ˆ μ—΄κ±° νƒ€μž…
enum Season {
    Spring,
    Summer,
    Autumn,
    Winter
}
enum LoginResult {
	LOGIN_SUCCESS,
	LOGIN_FAILED
}

Enum μ°Έμ‘° 방식

Enum νƒ€μž… 객체도 ν•˜λ‚˜μ˜ 데이터 νƒ€μž…μ΄λ―€λ‘œ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜κ³  μ‚¬μš©ν•˜λ©΄ λœλ‹€.

// μ—΄κ±°νƒ€μž… λ³€μˆ˜ = μ—΄κ±°νƒ€μž….μ—΄κ±°μƒμˆ˜;
Week monday = Week.MONDAY;
Week sunday = Week.SUNDAY;

ν•œκ°€μ§€ μ•Œμ•„λ‘˜ 점은 enum νƒ€μž…μ€ νŠΉμˆ˜ν•œ 클래슀 λΌλŠ” 점이닀.

즉, primitive νƒ€μž…μ΄ μ•„λ‹Œ referece νƒ€μž…μœΌλ‘œ λΆ„λ₯˜λ˜λ©°, κ·Έλž˜μ„œ enum μƒμˆ˜κ°’μ€ νž™(heap) μ˜μ—­μ— μ €μž₯되게 λœλ‹€.

enum-heap

 

String 처럼 μŠ€νƒ μ˜μ—­μ— μžˆλŠ” λ³€μˆ˜λ“€μ΄ νž™ μ˜μ—­μ— μžˆλŠ” λ°μ΄ν„°μ˜ μ£Όμ†Œκ°’μ„ μ €μž₯ν•¨μœΌλ‘œμ¨ μ°Έμ‘° ν˜•νƒœλ₯Ό λ„κ²Œ λœλ‹€. κ·Έλž˜μ„œ λ‹€μŒκ³Ό 같이 같은 enum νƒ€μž… λ³€μˆ˜ 끼리 같은 μƒμˆ˜ 데이터λ₯Ό λ°”λΌλ΄„μœΌλ‘œμ¨ λ‘˜μ΄ μ£Όμ†Œλ₯Ό λΉ„κ΅ν•˜λŠ” == μ—°μ‚° κ²°κ³ΌλŠ” trueκ°€ 되게 λœλ‹€.

Week today = null; // μ°Έμ‘° νƒ€μž…μ΄κΈ° λ•Œλ¬Έμ— null도 μ €μž₯ κ°€λŠ₯
today = Week.SUNDAY;

// μ£Όμ†Œκ°’ 비ꡐ
System.out.println(today == Week.SUNDAY); // true

enum-heap

 

λ§ˆμ°¬κ°€μ§€λ‘œ enum μƒμˆ˜λ“€μ„ λ°°μ—΄λ‘œ λ§Œλ“€μ–΄ μ €μž₯ν• μ‹œμ—λ„, 각 λ°°μ—΄ μ›μ†Œλ“€ λ§ˆλ‹€ μ°Έμ‘° μ£Όμ†Œκ°’λ“€μ΄ μ €μž₯λ˜μ–΄ νž™ μ˜μ—­μ˜ μƒμˆ˜ 데이터듀을 κ°€λ¦¬ν‚€κ²Œ λœλ‹€.

// enum Week 의 λͺ¨λ“  μƒμˆ˜κ°’λ“€μ„ λ°°μ—΄λ‘œ λ³€ν™˜
Week[] days = Week.values();

enum-heap


Enum λ©”μ†Œλ“œ μ’…λ₯˜

String 같은 μžλ°”μ˜ μ—¬λŸ¬ ν΄λž˜μŠ€κ°€ 자체 λ‚΄μž₯ λ©”μ†Œλ“œλ₯Ό 가지고 μžˆλ“―μ΄, enum μ—­μ‹œ λ‚΄μž₯ λ©”μ†Œλ“œλ₯Ό μ§€λ‹ˆκ³  μžˆλ‹€.

λͺ¨λ“  Enum νƒ€μž…μ€ 컴파일 μ‹œμ— java.lang.Enum ν΄λž˜μŠ€λ₯Ό μƒμ†ν•˜κ²Œ λ˜μ–΄μžˆκΈ° λ•Œλ¬Έμ—, java.lang.Enum μ— μ„ μ–Έλœ λ©”μ†Œλ“œλ₯Ό μ΄μš©ν•  수 μžˆλ‹€.

Enum 객체가 κ°€μ§€λŠ” λ©”μ†Œλ“œλŠ” μ•„λž˜μ™€ κ°™λ‹€

λ©”μ†Œλ“œ μ„€λͺ… 리턴 νƒ€μž…
name() μ—΄κ±° 객체의 λ¬Έμžμ—΄μ„ 리턴 String
ordinal() μ—΄κ±° 객체의 순번(0λΆ€ν„° μ‹œμž‘)을 리턴 int
compareTo() μ—΄κ±° 객체λ₯Ό λΉ„κ΅ν•΄μ„œ 순번 차이λ₯Ό 리턴 int
valueOf(String name) λ¬Έμžμ—΄μ„ μž…λ ₯λ°›μ•„μ„œ μΌμΉ˜ν•˜λŠ” μ—΄κ±° κ°μ²΄λ₯Ό λ¦¬ν„΄ enum
values() λͺ¨λ“  μ—΄κ±° 객체듀을 λ°°μ—΄λ‘œ 리턴 enum[]
enum Week {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}

 

name() λ©”μ†Œλ“œ

  • μ—΄κ±° 객체가 가지고 μžˆλŠ” λ¬Έμžμ—΄μ„ 리턴
  • λ°˜ν™˜λ˜λŠ” λ¬Έμžμ—΄μ€ μ—΄κ±° νƒ€μž…μ„ μ •μ˜ν•  λ•Œ μ‚¬μš©ν•œ μƒμˆ˜ 이름과 동일
Week w = Week.FRIDAY;

// μ—΄κ±° 객체의 λ¬Έμžμ—΄μ„ 리턴
String weekName = w.name();
System.out.println(weekName); // Spring

 

ordinal() λ©”μ†Œλ“œ

  • μ—΄κ±° νƒ€μž…μ„ μ •μ˜ ν•  λ•Œ 주어진 μˆœλ²ˆμ„ 리턴
  • 전체 μ—΄κ±° 객체 쀑 λͺ‡ 번째 μ—΄κ±° 객체인지 μ•Œλ €μ€€λ‹€
Week w = Week.FRIDAY;

// μ—΄κ±° 객체의 순번(0λΆ€ν„° μ‹œμž‘)을 리턴
// 전체 μ—΄κ±° 객체 쀑 λͺ‡ 번째 μ—΄κ±° 객체인지 μ•Œλ €μ€€λ‹€
int weekNum = w.ordinal();
System.out.println(weekNum); // 4

 

compareTo() λ©”μ†Œλ“œ

  • λ§€κ°œκ°’μœΌλ‘œ 주어진 μ—΄κ±° 객체λ₯Ό λΉ„κ΅ν•΄μ„œ 순번 차이λ₯Ό 리턴
  • μ—΄κ±° 객체가 λ§€κ°œκ°’μ˜ μ—΄κ±° 객체보닀 순번이 λΉ λ₯΄λ‹€ → 음수λ₯Ό 리턴
  • μ—΄κ±° 객체가 λ§€κ°œκ°’μ˜ μ—΄κ±° 객체보닀 순번이 λŠ¦λ‹€ → μ–‘μˆ˜λ₯Ό 리턴
// μ—΄κ±° 객체λ₯Ό λΉ„κ΅ν•΄μ„œ 순번 차이λ₯Ό 리턴 (μ‹œμž‘μ μ„ μ–΄λŠ μ—΄κ±° 객체의 κΈ°μ€€μœΌλ‘œ λͺ‡λ²ˆμ§Έ μœ„μΉ˜ν•˜λŠ”μ§€)
Week w1 = Week.TUESDAY; // 2
Week w2 = Week.SATURDAY; // 6

// μ—΄κ±° 객체가 λ§€κ°œκ°’μ˜ μ—΄κ±° 객체보닀 순번이 λΉ λ₯΄λ‹€ → 음수λ₯Ό 리턴
int compare1 = w1.compareTo(w2); // SATURDAY κΈ°μ€€μœΌλ‘œ TUESDAY μœ„μΉ˜ (6μ—μ„œ 2κ°€ 되기 μœ„ν•œ κ°’)
System.out.println(compare1); // -4

// μ—΄κ±° 객체가 λ§€κ°œκ°’μ˜ μ—΄κ±° 객체보닀 순번이 λŠ¦λ‹€ → μ–‘μˆ˜λ₯Ό 리턴
int compare2 = w2.compareTo(w1); // TUESDAY κΈ°μ€€μœΌλ‘œ SATURDAY μœ„μΉ˜ (2μ—μ„œ 6κ°€ 되기 μœ„ν•œ κ°’)
System.out.println(compare2); // 4

 

valueOf() λ©”μ†Œλ“œ

  • λ§€κ°œκ°’μœΌλ‘œ μ£Όμ–΄μ§€λŠ” λ¬Έμžμ—΄κ³Ό λ™μΌν•œ λ¬Έμžμ—΄μ„ κ°€μ§€λŠ” μ—΄κ±° 객체λ₯Ό 리턴
// λ¬Έμžμ—΄μ„ μž…λ ₯λ°›μ•„μ„œ μΌμΉ˜ν•˜λŠ” μ—΄κ±° 객체λ₯Ό 리턴
Week w3 = Week.valueOf("SUNDAY"); // w3 λ³€μˆ˜λŠ” Week.SUNDAY μ—΄κ±° 객체λ₯Ό μ°Έμ‘°ν•˜κ²Œ 됨
System.out.println(w3); // SUNDAY

 

values() λ©”μ†Œλ“œ

  • μ—΄κ±° νƒ€μž…μ˜ λͺ¨λ“  μ—΄κ±° 객체듀을 λ°°μ—΄λ‘œ λ§Œλ“€μ–΄ 리턴
// λͺ¨λ“  μ—΄κ±° 객체듀을 λ°°μ—΄λ‘œ 리턴
Week[] w4 = Week.values();

System.out.println(Arrays.toString(w4)); // [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]

for (Week type : Week.values()) { // μ—΄κ±° 순회
    System.out.println(type);  // μˆœμ„œλŒ€λ‘œ μ—΄κ±° 객체 좜λ ₯
}

java.lang.Enum 클래슀

λͺ¨λ“  ν΄λž˜μŠ€κ°€ Object 클래슀λ₯Ό μžλ™ μƒμ†ν•˜λŠ” 것 처럼, Enum ν΄λž˜μŠ€λ„ 무쑰건 java.lang.Enum μ΄λΌλŠ” 클래슀의 상속을 λ°›λŠ”λ‹€. 그리고 java.lang.Enum ν΄λž˜μŠ€μ— μ •μ˜λ˜μ–΄ μžˆλŠ” λ©”μ†Œλ“œλ₯Ό 가져와 μ‚¬μš©ν•˜λŠ” 것이닀.

java.lang.Enum

  • String name : Enum (μ—΄κ±°)μƒμˆ˜μ˜ 이름
  • int ordinal : Enum의 μˆœμ„œ, μƒμˆ˜κ°€ μ„ μ–Έλœ μˆœμ„œλŒ€λ‘œ 0λΆ€ν„° μ¦κ°€ν•œλ‹€
  • protected Enum μƒμ„±μž : μ»΄νŒŒμΌλŸ¬μ—μ„œ μžλ™μœΌλ‘œ ν˜ΈμΆœλ˜λ„λ‘ 해놓은 μƒμ„±μžλ‹€. ν•˜μ§€λ§Œ, κ°œλ°œμžκ°€ 이 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•  μˆ˜λŠ” μ—†λ‹€.

λ§ˆμ°¬κ°€μ§€λ‘œ java.lang.Enum ν΄λž˜μŠ€λ„ Object 클래슀λ₯Ό μžλ™ μƒμ†ν•΄μ„œ, enumμ—μ„œλ„ Object 클래슀의 λ©”μ†Œλ“œλ₯Ό κ·ΈλŒ€λ‘œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.

ν•˜μ§€λ§Œ Enum ν΄λž˜μŠ€λŠ” κ°œλ°œμžλ“€μ΄ Object 클래슀 쀑 λ‹€μŒ 4개의 λ©”μ†Œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ”©ν•˜μ§€ λͺ»ν•˜λ„둝 λ©”μ†Œλ“œλ₯Ό final ν™” ν•˜μ—¬ λ§‰μ•„λ†“μ•˜λ‹€. μ™œλƒν•˜λ©΄ enum은 κ³ μœ ν•œ μƒμˆ˜μ΄κΈ° λ•Œλ¬Έμ— μ˜€λ²„λΌμ΄λ”©ν•΄μ„œ 자기 λ§ˆμŒλŒ€λ‘œ 바꿔버리면 κ³ μœ μ„±μ΄ 깨지기 λ•Œλ¬Έμ΄λ‹€.

λ©”μ†Œλ“œ λ‚΄μš©
clone() 객체λ₯Ό λ³΅μ œν•˜κΈ° μœ„ν•œ λ©”μ†Œλ“œ
ν•˜μ§€λ§Œ, 이 λ©”μ†Œλ“œλŠ” enum ν΄λž˜μŠ€μ—μ„œ μ‚¬μš©ν•˜λ©΄ μ•ˆλœλ‹€.
λ§Œμ•½ 호좜될 κ²½μš°μ—” CloneNotSupportedException μ΄λΌλŠ” μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚€λ„λ‘ λ˜μ–΄μžˆλ‹€
finalize() GCκ°€ λ°œμƒν•  λ•Œ μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ λ©”μ†Œλ“œ
hashCode() int νƒ€μž…μ˜ ν•΄μ‹œ μ½”λ“œ 값을 λ¦¬ν„΄ν•˜λŠ” λ©”μ†Œλ“œ
equals() 두 개의 객체가 λ™μΌν•œμ§€λ₯Ό ν™•μΈν•˜λŠ” λ©”μ†Œλ“œ

java.lang.Enum


Enum κ³ κΈ‰ 문법

 

Enum 맀핑

Season μ΄λΌλŠ” 4κ³„μ ˆ μƒμˆ˜λ₯Ό μ €μž₯ν•œ enum이 μžˆλŠ”λ°, 만일 SPRING μƒμˆ˜λ₯Ό κ°€μ Έμ˜€λ©΄ "λ΄„"μ΄λΌλŠ” μƒμˆ˜μ˜ 고유의 κ°’(value)을 λ¬Έμžμ—΄μ„ 좜λ ₯ν•˜κ²Œ λ§Œλ“€κ³  μ‹Άμ„λ•Œ enum을 λ§€ν•‘ν•΄μ„œ ꡬ성해쀄 수 μžˆλ‹€.

// enum 맀핑 클래슀
enum Season {
    SPRING("λ΄„"),
    SUMMER("여름"),
    FALL("가을"),
    WINTER("겨울");
	
    // λ¬Έμžμ—΄μ„ μ €μž₯ν•  ν•„λ“œ
    private String season;

	// μƒμ„±μž (싱글톀)
    private Season(String season) {
        this.season = season;
    }

	// Getter
    public String getSeason() {
        return season;
    }
}
public static void main(String[] args) throws Exception {
    Season s = Season.SUMMER;
    System.out.println(s.name()); // μ—΄κ±° 객체λͺ… 좜λ ₯ : SUMMER
    System.out.println(s.getSeason()); // λ§€ν•‘λœ μ—΄κ±° 데이터 좜λ ₯ : λ΄„
}

μ—΄κ±° 객체의 SPRING("λ΄„") μ—μ„œ "λ΄„" λ¬Έμžμ—΄μ΄ enum 클래슀 μƒμ„±μž μž…λ ₯κ°’μœΌλ‘œ λ“€μ–΄κ°€ private String season ν•„λ“œμ— λ‹΄κΈ°κ²Œ λœλ‹€. κ·Έλž˜μ„œ μ—΄κ±° 객체 λ³€μˆ˜μ—μ„œ getter λ©”μ„œλ“œ getSeason() λ₯Ό 톡해 ν•΄λ‹Ή μ—΄κ±° 객체에 λ§΅ν•‘λœ λ¬Έμžμ—΄μ„ κ°€μ Έμ˜¬ 수 μžˆλŠ” 것이닀.

enum μƒμˆ˜ 객체의 λ§€κ°œκ°’μœΌλ‘œ λ°˜λ“œμ‹œ ν•œκ°œλ§Œ λ“€μ–΄κ°ˆ ν•„μš”κ°€ μ—†λ‹€. 3개 정보 맀핑이 ν•„μš”ν•˜λ‹€λ©΄ enum 클래슀의 μƒμ„±μžμ˜ μ•„κ·œλ¨ΌνŠΈλ₯Ό 3개둜 μ§€μ •ν•˜λ©΄ λ˜λŠ” 일이닀.

enum

 

enum λ‚΄λΆ€ ꡬ성 μ΄ν•΄ν•˜κΈ°

λ‹¨μˆœνžˆ μ—΄κ±° μƒμˆ˜ 집합인쀄 μ•Œμ•˜λŠ”λ° enum을 μ΄λŸ°μ‹μœΌλ‘œ 이용이 κ°€λŠ₯ν•œ μ΄μœ λŠ”, 사싀 enum μƒμˆ˜ ν•˜λ‚˜λ‹Ή μžμ‹ μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό ν•˜λ‚˜μ”© λ§Œλ“€μ–΄ public static final ν•„λ“œλ‘œ κ³΅κ°œν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

즉, Season μ΄λΌλŠ” μ—΄κ±°ν˜• νƒ€μž…μ„ μš°λ¦¬κ°€ μ•„λŠ” 클래슀둜 ν‘œν˜„ν•˜μžλ©΄ λ‹€μŒκ³Ό 같이 ν‘œν˜„μ΄ κ°€λŠ₯ν•˜λ‹€λŠ” 것이닀.

/* νƒ€μž… μ•ˆμ „ μ—΄κ±° νŒ¨ν„΄(typesafe enum pattern) */
final class Season {
    public static final Season SPRING = new Season("SPRING"); // μžκΈ°μžμ‹ μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€μ–΄ μƒμˆ˜ν™”
    public static final Season SUMMER = new Season("SUMMER");
    public static final Season AUTUMN = new Season("AUTUMN");
    public static final Season WINTER = new Season("WINTER");
    
    private String season;
    
    private Season(String season) {
        this.season = season;
    }
    
    public String getSeason() {
        return season;
    }
}
μ‹€μ œλ‘œ enum이 λ‚˜μ˜€κΈ°μ „ jdk 1.5 λ°‘ λ²„μ „μ—μ„œλŠ” μ΄λ ‡κ²Œ μ‚¬μš©λ˜μ—ˆλ‹€.

이처럼 각 enum κ°μ²΄λ§ˆλ‹€ μžμ‹ μ˜ 클래슀λ₯Ό μΈμŠ€ν„΄μŠ€ν™” ν•˜μ—¬ μ €μž₯ν•˜λ‹ˆ enum을 λ§€ν•‘ν•œλ‹€κ±°λ‚˜ μΆ”μƒλ©”μ†Œλ“œ ν™•μž₯ν•œλ‹€κ±°λ‚˜ λ“± μ‘μš©μ΄ κ°€λŠ₯ν•œ 것이닀.

그리고 μœ„μ˜ μ½”λ“œλ₯Ό 보면 μƒμ„±μž μžμ²΄κ°€ private μ ‘κ·Όμ œμ–΄μž 이기 λ•Œλ¬Έμ—, λ°–μ—μ„œ μ ‘κ·Όν•  수 μžˆλŠ” μƒμ„±μžλ₯Ό μ œκ³΅ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ 사싀상 final이 되게 λœλ‹€. κ·Έλž˜μ„œ ν΄λΌμ΄μ–ΈνŠΈκ°€ μΈμŠ€ν„΄μŠ€λ₯Ό 직접 μƒμ„±ν•˜κ±°λ‚˜ ν™•μž₯ν•  수 μ—†μœΌλ‹ˆ μ—΄κ±° νƒ€μž… μ„ μ–ΈμœΌλ‘œ λ§Œλ“€μ–΄μ§„ μΈμŠ€ν„΄μŠ€λ“€μ€ λ”± ν•˜λ‚˜μ”©λ§Œ μ‘΄μž¬ν•¨μ΄ 보μž₯λœλ‹€.

 

enum은 λ°μ΄ν„°μ˜ κ·Έλ£Ήν™” 및 관리에 용이

데이터듀이 μ„œλ‘œ κ΄€λ ¨λ˜μ–΄ μžˆμ§€λ§Œ κ΄€λ ¨λœ ν˜•νƒœλ₯Ό κ΅¬ν˜„ν•˜λŠ”λ° μžˆμ–΄ μ• λ‘œμ‚¬ν•­μ΄ 생긴닀면 enum을 톡해 ν•œ 클래슀 λ‚΄μ—μ„œ 관리할 수 있게 λœλ‹€.

예λ₯Όλ“€μ–΄ 체크 μΉ΄λ“œλ₯Ό 닀룬닀고 ν•œλ‹€λ©΄, μΉ΄λ“œμ‚¬ λ§ˆλ‹€ λ‹€λ₯΄λ©° μ‹ ν•œ μΉ΄λ“œλ₯Ό 쓰더라도 또 μ—¬λŸ¬κ°€μ§€ μΉ΄λ“œ μ’…λ₯˜κ°€ μžˆμ„ν…λ°, 본래라면 'μΉ΄λ“œμ‚¬' ν΄λž˜μŠ€μ™€ 'μΉ΄λ“œμ’…λ₯˜' 클래슀 μ΄λ ‡κ²Œ λ‘κ°œλ‘œ λ‚˜λˆ„μ–΄ μ„œλ‘œ μ—°κ΄€λ˜κ²Œ μ½”λ“œλ₯Ό ꡬ성해야 λœλ‹€.

ν•˜μ§€λ§Œ enum을 μ΄μš©ν•˜λ©΄ ν•œλˆˆμ— 보기 μ‰½κ²Œ μ•„λž˜ 처럼 ꡬ성이 κ°€λŠ₯ν•˜μ—¬ 관계λ₯Ό κ°€μ‹œμ μœΌλ‘œ ν‘œν˜„ν•  수 μžˆλ‹€. 그리고 μ μ ˆν•˜κ²Œ λ©”μ†Œλ“œ λ‘œμ§μ„ enum 객체 λ‚΄ μ•ˆμ— κ΅¬ν˜„ν•΄μ€€λ‹€λ©΄ κ°•λ ₯ν•œ μƒμˆ˜ 클래슀λ₯Ό κ΅¬ν˜„ν•  수 있게 λœλ‹€.

enum CreditCard {

    SHINHAN("μ‹ ν•œ", Arrays.asList("Mr.Life μΉ΄λ“œ", "Deep Dream μΉ΄λ“œ", "Deep Oil μΉ΄λ“œ")),
    KB("κ΅­λ―Ό", Arrays.asList("톑톑D μΉ΄λ“œ", "ν‹°νƒ€λŠ„ μΉ΄λ“œ", "λ‹€λ‹΄ μΉ΄λ“œ")),
    NH("λ†ν˜‘", Arrays.asList("μ˜¬λ°”λ₯Έ FLEX μΉ΄λ“œ", "ν…Œμ΄ν¬ 5 μΉ΄λ“œ", "NH μ˜¬μ› νŒŒμ΄μΉ΄λ“œ"));

    private final String Enterprise;
    private final List<String> cards;

    CreditCard(String name, List<String> cards) {
        this.Enterprise = name;
        this.cards = cards;
    }
	
    String getCard(String cardName) {
        return Arrays.stream(CreditCard.values())
                .filter(creditCard -> creditCard.equals(cardName))
                .findFirst()
                .orElseThrow(Exception::new);
    }
}

Enum ν™•μž₯

enum 맀핑 κΈ°λŠ₯을 ν™•μž₯ν•˜μ—¬, enum을 λ‹¨μˆœνžˆ μƒμˆ˜ 값을 λ„˜μ–΄μ„œ μƒμˆ˜ λ©”μ†Œλ“œλ‘œμ„œλ„ 이용이 κ°€λŠ₯ν•˜λ‹€.

μœ„μ—μ„œ enum 맀핑은 클래슀 ν•„λ“œμ™€ μƒμ„±μžλ₯Ό μ •μ˜ν•΄μ„œ μƒμˆ˜μ˜ λ§€κ°œλ³€μˆ˜κ°’μ„ ν•„λ“œμ— μ €μž₯ν•˜κ³  μΈμŠ€ν„΄μŠ€ν™” ν•¨μœΌλ‘œμ¨ κ³ μœ ν•œ μƒμˆ˜ κ°μ²΄λ‘œμ„œ ν™œμš©ν–ˆμ—ˆλ‹€.

μ—¬κΈ°μ„œ 더 λ‚˜μ•„κ°€ 좔상 λ©”μ†Œλ“œλ₯Ό μ •μ˜ν•΄μ„œ 각 μƒμˆ˜λ§ˆλ‹€ 읡λͺ… 클래슀 처럼 λ©”μ†Œλ“œ μž¬μ •μ˜λ₯Ό ν•˜κ²Œ ν•΄μ„œ 각 μƒμˆ˜λ§ˆλ‹€ λ‹€λ₯Έ 역할을 ν•˜λŠ” λ©”μ†Œλ“œλ₯Ό κ°–κ²Œ λ˜λŠ” 원리이닀.

enum Operation {
    PLUS("+") {
        public double apply(double x, double y) {
            return x + y;
        }
    },
    MINUS("-") {
        public double apply(double x, double y) {
            return x - y;
        }
    },
    MULTI("*") {
        public double apply(double x, double y) {
            return x * y;
        }
    },
    DIVIDE("/") {
        public double apply(double x, double y) {
            return x / y;
        }
    };

    // 클래슀 μƒμ„±μžμ™€ 멀버
    private final String symbol;
    Operation(String symbol) {
        this.symbol = symbol;
    }

    // toString을 μž¬μ •μ˜ν•˜μ—¬ μ—΄κ±° 객체의 λ§€ν•‘λœ λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•˜λ„λ‘
    @Override
    public String toString() {
        return symbol;
    }

    // μ—΄κ±° 객체의 λ©”μ†Œλ“œμ— μ‚¬μš©λ  좔상 λ©”μ†Œλ“œ μ •μ˜
    public abstract double apply(double x, double y);
}

enum-abstract

public static void main(String[] args) {
    double x = 2.5;
    double y = 5.0;

    // Operation μƒμˆ˜μ§‘ν•©μ˜ PLUS μƒμˆ˜λ₯Ό μ •μ˜
    Operation plus = Operation.PLUS;

    // enum 맀핑값 좜λ ₯
    String name = plus.toString();
    System.out.println(name); // +

    // enum ν™•μž₯ λ©”μ†Œλ“œ μ‹€ν–‰
    double result = plus.apply(x, y); // λ§μ…ˆμ„ μˆ˜ν–‰ν•˜λŠ” λ©”μ†Œλ“œ (Operation.PLUS.apply(x, y) 둜 해도됨)
    System.out.println(result); // 7.5

    // ------------------------------------------------------------------- //

    // Operation μƒμˆ˜μ§‘ν•©μ˜ PLUS μƒμˆ˜λ₯Ό μ •μ˜
    Operation multi = Operation.MULTI;

    String name = plus.toString();
    System.out.println(name); // *

    // enum ν™•μž₯ λ©”μ†Œλ“œ μ‹€ν–‰
    double result2 = multi.apply(x, y); // κ³±μ…ˆμ„ μˆ˜ν–‰ν•˜λŠ” λ©”μ†Œλ“œ
    System.out.println(result2); // 12.5
}

 

enum은 μƒνƒœμ™€ ν–‰μœ„λ₯Ό ν•œκ³³μ—μ„œ 관리가 κ°€λŠ₯

이처럼 enum을 λ‹¨μˆœνžˆ μƒμˆ˜ ν‘œν˜„μ‹μ„ λ„˜μ–΄μ„œ λ™μž‘, ν–‰μœ„λ₯Ό μˆ˜ν–‰ν•˜λŠ” μƒμˆ˜λ‘œμ„œλ„ μ‘μš© ν™•μž₯이 κ°€λŠ₯ν•˜λ‹€. μƒμˆ˜ μƒνƒœμ™€ ν–‰μœ„λ₯Ό ν•œ κ³³μ—μ„œ 관리가 κ°€λŠ₯ν•œ 것이닀.

처음 λ°°μšΈλ•ŒλŠ” 글쓴이도 κ³΅κ°ν• μ •λ„λ‘œ 맀우 ν˜Όλž€μŠ€λŸ½κ² μ§€λ§Œ, 이 뢀뢄은 μ™œ μžλ°”μ˜ Enum이 κ°•λ ₯ν•œμ§€ λ³΄μ—¬μ£ΌλŠ” λŒ€λͺ©μ΄κΈ°λ„ ν•œλ‹€.

 

예λ₯Όλ“€μ–΄ κ° μƒμˆ˜λ₯Ό νŠΉμ • 데이터와 μ—°κ²°μ§“κ±°λ‚˜, μƒμˆ˜λ§ˆλ‹€ λ‹€λ₯΄κ²Œ λ™μž‘ν•˜κ²Œ ν•˜λŠ” 둜직이 ν•„μš”ν• λ•Œ, 보톡이라면 λ‹¨μˆœνžˆ ifλ¬Έ, switch문으둜 μƒμˆ˜λ₯Ό λΆ„κΈ°ν•˜μ—¬ ν•˜μ—¬ 각 λ©”μ†Œλ“œλ“€μ„ μ‹€ν–‰ν•˜λŠ” 것이 일반적인 둜직이기 λ§ˆλ ¨μ΄λ‹€.

κ·ΈλŸ¬λ‚˜ μ΄λŸ¬ν•œ μ½”λ“œ ꡬ성은 κ°’(μƒνƒœ)κ³Ό λ©”μ†Œλ“œ(ν–‰μœ„)κ°€ μ–΄λ–€ 관계가 μžˆλŠ”μ§€μ— λŒ€ν•΄ μ½”λ“œ μ •μ˜λ¬Έμ„ μ°Ύμ•„ 기웃거리며 νŒŒμ•…ν•΄μ•Ό ν•˜λŠ” μ‹œκ°„μ΄ κ±Έλ¦°λ‹€.

class Operation {

    public void caclulate(String oper) {
        if ("+".equals(oper)) {
            plus();
        } else if ("-".equals(oper)) {
            minus();
        } else if ("*".equals(oper)) {
            multi();
        } else if ("/".equals(oper)) {
            divide();
        }
    }

    void plus() { ... }

    void minus() { ... }

    void multi() { ... }

    void divide() { ... }
}

ν•˜μ§€λ§Œ enum을 μ΄μš©ν•˜λ©΄ μƒνƒœμ™€ ν–‰μœ„λ₯Ό ν•œλˆˆμ— νŒŒμ•…μ΄ κ°€λŠ₯ν•˜λ‹€.

객체 지ν–₯' 적으둜 μ½”λ“œλ₯Ό νŒ¨ν„΄ν™”ν•˜μ—¬ μœ μ§€ λ³΄μˆ˜ν•˜κΈ° μš©μ΄ν•˜κ²Œ λ§Œλ“œλŠ” κ²ƒμœΌλ‘œ 보면 λœλ‹€.

enum-abstract

 

λžŒλ‹€μ‹μœΌλ‘œ enum을 더 κΉ”λ”ν•˜κ²Œ

결ꡭ은 enum에 읡λͺ… 클래슀λ₯Ό μ μš©ν•œ κΌ΄κ³Ό κ°™μœΌλ‹ˆ, λžŒλ‹€ ν‘œν˜„μ‹μ„ 톡해 μœ„μ˜ κΈ°λ‚˜κΈ΄ μ½”λ“œλ₯Ό κΉ”λ”ν•˜κ²Œ λ§Œλ“€ 수 μžˆλ‹€.

// ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ μž„ν¬νŠΈ
import java.util.function.DoubleBinaryOperator;

enum Operation {
    PLUS("+", (x, y) -> x + y),
    MINUS("-", (x, y) -> x - y),
    TIMES("*", (x, y) -> x * y),
    DIVIDE("/", (x, y) -> x / y);

    private final DoubleBinaryOperator op; // λžŒλ‹€μ‹μ„ μ €μž₯ν•  ν•„λ“œ

    private final String symbol;

    Operation(String symbol, DoubleBinaryOperator op) {
        this.symbol = symbol;
        this.op = op;
    }

    @Override
    public String toString() { return symbol; }

    public double apply(double x, double y) {
        return op.applyAsDouble(x, y);
    }
}

enum-lambda


Enum κ³Ό 싱글톀 관계

μžλ°”μ—μ„œμ˜ enum μ—΄κ±° νƒ€μž…μ€ μΌμ’…μ˜ 클래슀이며 μƒμˆ˜ ν•˜λ‚˜λ‹Ή μžμ‹ μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό ν•˜λ‚˜μ”© λ§Œλ“€μ–΄ public static final ν•„λ“œλ‘œ κ³΅κ°œν•˜κ²Œ λœλ‹€. ν•˜μ§€λ§Œ enum은 클래슀처럼 μ΄μš©ν• μˆ˜λŠ” μžˆμ§€λ§Œ μΈμŠ€ν„΄μŠ€ν™”λŠ” ν• μˆ˜λŠ” μ—†λŠ”λ°, μ‹€μ œλ‘œ new ν‚€μ›Œλ“œλ‘œ μΈμŠ€ν„΄μŠ€ 생성을 ν•˜λ €κ³  ν•˜λ©΄ μ—λŸ¬κ°€ λ‚œλ‹€.

μ΄λŸ¬ν•œ μ œμ•½μ μΈ νŠΉμ§•μ„ 가지고 μžˆλŠ” μ΄μœ λŠ” enum νƒ€μž…μ€ κ³ μ •λœ μƒμˆ˜λ“€μ˜ μ§‘ν•©μœΌλ‘œμ¨, λŸ°νƒ€μž„(run-time)이 μ•„λ‹Œ μ»΄νŒŒμΌνƒ€μž„(compile-time)에 λͺ¨λ“  값을 μ•Œκ³  μžˆμ–΄μ•Ό ν•˜λŠ” κ·œμΉ™μ΄ 있기 λ•Œλ¬Έμ΄λ‹€. 즉, λ‹€λ₯Έ νŒ¨ν‚€μ§€λ‚˜ ν΄λž˜μŠ€μ—μ„œ enum νƒ€μž…μ— μ ‘κ·Όν•΄μ„œ λ³€μˆ˜ 처럼 λ™μ μœΌλ‘œ μ–΄λ– ν•œ 값듀을 ν• λ‹Ήν•΄ μ£ΌλŠ” ν–‰μœ„λŠ” κΈˆμ§€λœ 것이닀. 

이 λ•Œλ¬Έμ— enum 객체의 μƒμ„±μžμ˜ μ ‘κ·Όμ œμ–΄μžλ₯Ό private으둜 μ„€μ •ν•΄μ•Ό ν•œλ‹€. μ΄λ ‡κ²Œ 되면 μ™ΈλΆ€μ—μ„œ μ ‘κ·Ό κ°€λŠ₯ν•œ μƒμ„±μžκ°€ μ—†μœΌλ―€λ‘œ enumνƒ€μž…μ€ μ‹€μ œμ μœΌλ‘œ final ν΄λž˜μŠ€μ™€ 닀름이 μ—†κ²Œ λœλ‹€.

μ΄λŸ¬ν•œ νŠΉμ„± λ•Œλ¬Έμ—, enumνƒ€μž…μ€ 싱글톀을 κ΅¬ν˜„ν•˜λŠ” ν•˜λ‚˜μ˜ λ°©λ²•μœΌλ‘œ μ‚¬μš©λ˜κΈ°λ„ ν•œλ‹€.

 

[GOF] πŸ’  싱글톀(Singleton) νŒ¨ν„΄ - κΌΌκΌΌν•˜κ²Œ μ•Œμ•„λ³΄μž

Singleton Pattern 싱글톀 νŒ¨ν„΄μ€ λ””μžμΈ νŒ¨ν„΄λ“€ μ€‘μ—μ„œ κ°€μž₯ κ°œλ…μ μœΌλ‘œ κ°„λ‹¨ν•œ νŒ¨ν„΄μ΄λ‹€. ν•˜μ§€λ§Œ κ°„λ‹¨ν•œ 만큼 이 νŒ¨ν„΄μ— λŒ€ν•΄ μ½”λ“œλ§Œ 던져주고 λλ‚΄λ²„λ¦¬λŠ” κ²½μš°κ°€ μžˆμ–΄, 어디에 μ“°μ΄λŠ”μ§€ μ–΄λ– ν•œ λ¬Έ

inpa.tistory.com

enum SingletonEnum {
    INSTANCE;
 
    private final Client dbClient;
	
    SingletonEnum() {
        dbClient = Database.getClient();
    }
 
    public static SingletonEnum getInstance() {
        return INSTANCE;
    }
 
    public Client getClient() {
        return dbClient;
    }
}
 
public class Main {
    public static void main(String[] args) {
        SingletonEnum singleton = SingletonEnum.getInstance();
        singleton.getClient();
    }
}

# 참고자료

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

이것이 μžλ°”λ‹€ - μ‹ μš©κΆŒμ˜ Java ν”„λ‘œκ·Έλž˜λ° 정볡

https://github.com/yeGenieee/java-live-study/blob/main/%5B11%5DJava%20Live%20Study.md