πŸ“– Enum μ—΄κ±°ν˜•


μ—΄κ±°ν˜•μ΄λž€?

JDK 1.5 λΆ€ν„° μƒˆλ‘œ μΆ”κ°€λœ κ°œλ…μ΄λ‹€.

기쑴의 μ–Έμ–΄λ“€κ³Ό μžλ°”μ˜ Enum이 λ‹€λ₯Έ 점은

  • μ—΄κ±°ν˜•μ΄ κ°–λŠ” κ°’ 뿐만 μ•„λ‹ˆλΌ νƒ€μž…κΉŒμ§€ κ΄€λ¦¬ν•˜κΈ° λ•Œλ¬Έμ— 보닀 논리적인 였λ₯˜λ₯Ό 쀄일 수 μžˆλ‹€.
  • β€˜νƒ€μž…μ— μ•ˆμ „ν•œ μ—΄κ±°ν˜•β€™μ„ μ œκ³΅ν•˜μ—¬ μ‹€μ œ 값이 같아도 νƒ€μž…μ΄ λ‹€λ₯΄λ©΄ 쑰건식 κ²°κ³Όκ°€ false이닀. κ°’ 뿐만 μ•„λ‹ˆλΌ νƒ€μž…κΉŒμ§€ μ²΄ν¬ν•œλ‹€.
  • μƒμˆ˜ 값이 λ°”λ€Œμ–΄λ„ κΈ°μ‘΄ μ†ŒμŠ€λ₯Ό λ‹€μ‹œ μ»΄νŒŒμΌν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

μ—΄κ±°ν˜•μ˜ μ •μ˜μ™€ μ‚¬μš©

enum μ—΄κ±°ν˜•μ΄λ¦„ {μƒμˆ˜λͺ…1, μƒμˆ˜λͺ…2, ...}

μ—΄κ±°ν˜•μ— μ •μ˜λœ μƒμˆ˜λ₯Ό μ‚¬μš”μ•„λŠ” 방법은 μ—΄κ±°ν˜•μ΄λ¦„.μƒμˆ˜λͺ…이닀.
클래슀의 static λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λŠ” 것과 λ™μΌν•˜λ‹€.

μ—΄κ±°ν˜• μƒμˆ˜κ°„ 비ꡐ

== μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜μ—¬ 비ꡐ할 수 μžˆλ‹€.
equals()κ°€ μ•„λ‹Œ ==으둜 비ꡐ가 κ°€λŠ₯ν•˜λ‹€λŠ” 것은 그만큼 μ„±λŠ₯이 μ’‹λ‹€λŠ” 것이닀.
<, >λ‘œλŠ” 비ꡐ할 수 μ—†μ§€λ§Œ compareTo()λŠ” μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.

또 switch 문의 쑰건식에도 μ‚¬μš©ν•  수 μžˆλ‹€.

switch(d1) {
    case EAST: // Direction.EAST라고 μ“°λ©΄ μ•ˆλœλ‹€.
        System.out.println("The direction is EAST."); 
        break;
    case SOUTH:
        System.out.println("The direction is SOUTH."); 
        break;
    case WEST:
        System.out.println("The direction is WEST."); 
        break;
    case NORTH:
        System.out.println("The direction is NORTH."); 
        break;
    default:
        System.out.println("Invalid direction."); 
        break;
    }

λ‹€μ–‘ν•œ λ©”μ†Œλ“œ

μ—΄κ±°ν˜•μ— μ •μ˜λœ λͺ¨λ“  μƒμˆ˜λ₯Ό 좜λ ₯ν•˜λ €λ©΄ λ‹€μŒκ³Ό 같이 ν•œλ‹€.

Direction[] dArr = Direction.values();

for(Direction d : dArr ) 
    System.out.printf("%s=%d%n", d.name(), d.original());
  • values() : μ—΄κ±°ν˜•μ˜ λͺ¨λ“  μƒμˆ˜λ₯Ό 배열에 λ‹΄μ•„ λ°˜ν™˜ν•œλ‹€.
  • ordinal() : λͺ¨λ“  μ—΄κ±°ν˜•μ˜ 쑰상인 java.lang.Enum ν΄λž˜μŠ€μ— μ •μ˜λœ κ²ƒμœΌλ‘œ, μ •μ˜λœ μˆœμ„œλ₯Ό μ •μˆ˜λ‘œ λ°˜ν™˜ν•œλ‹€.
  • name() : μ—΄κ±°ν˜• μƒμˆ˜μ˜ 이름을 λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•œλ‹€.
  • valueOf() : μ§€μ •λœ μ—΄κ±°ν˜•μ—μ„œ nameκ³Ό μΌμΉ˜ν•˜λŠ” μ—΄κ±°ν˜• μƒμˆ˜λ₯Ό λ°˜ν™˜ν•œλ‹€.

μ—΄κ±°ν˜•μ˜ μƒμ„±μž

Enum νƒ€μž…μ€ μ—΄κ±°ν˜•μ„ μ˜λ―Έν•˜λŠ” νŠΉλ³„ν•œ ν˜•νƒœμ˜ 클래슀이기 λ•Œλ¬Έμ— 일반 ν΄λž˜μŠ€μ™€ 같이
μƒμ„±μžκ°€ μ‘΄μž¬ν•˜μ—¬μ•  ν•œλ‹€. μžλ°”κ°€ κΈ°λ³Έ μƒμ„±μžλ₯Ό λ§Œλ“€μ–΄μ£ΌκΈ΄ ν•˜μ§€λ§Œ,
μ—΄κ±°ν˜•μ˜ μƒμ„±μžλŠ” μ œμ–΄μžκ°€ λ¬΅μ‹œμ μœΌλ‘œ private으둜 μ§€μ •ν•΄μ€˜μ•Ό ν•œλ‹€.

μ΄μœ λŠ” κ³ μ •λœ μƒμˆ˜μ˜ μ§‘ν•©μœΌλ‘œ λŸ°νƒ€μž„μ΄ μ•„λ‹Œ 컴파일 νƒ€μž„μ— λͺ¨λ“  값을
μ•Œκ³  μžˆμ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.
즉, λ‹€λ₯Έ νŒ¨ν‚€μ§€λ‚˜ ν΄λž˜μŠ€μ—μ„œ μ ‘κ·Όν•΄ λ™μ μœΌλ‘œ 값을 ν• λ‹Ήν•  수 μ—†λ‹€.

μ—΄κ±°ν˜•μ— 멀버 μΆ”κ°€ν•˜κΈ°

oridinal()이 μ—΄κ±°ν˜• μƒμˆ˜κ°€ μ •μ˜λœ μˆœμ„œλ₯Ό λ°˜ν™˜ν•˜μ§€λ§Œ,
내뢀적인 μš©λ„λ‘œλ§Œ μ‚¬μš©λ˜κΈ° μœ„ν•œ 것이기 λ•Œλ¬Έμ— μ—΄κ±°ν˜• μƒμˆ˜μ˜ κ°’μœΌλ‘œ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€.

μ—΄κ±° μƒμˆ˜μ˜ 값이 λΆˆκ·œμΉ™μ μΈ κ²½μš°μ—λŠ” λ‹€μŒκ³Ό 같이 μ—΄κ±°ν˜• μƒμˆ˜ 이름 μ˜†μ—
μ›ν•˜λŠ” 값을 κ΄„ν˜Έμ™€ ν•¨κ»˜ 적어쀀닀.
그리고 μ§€μ •λœ 값을 μ €μž₯ν•  수 μžˆλŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ™€ μƒμ„±μžλ₯Ό μƒˆλ‘œ μΆ”κ°€ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.

enum Direction {
    EAST(1), SOUTH(5), WEST(-1), NORTH(10);
    
    private final int value; // μ •μˆ˜λ₯Ό μ €μž₯ν•  ν•„λ“œ(μΈμŠ€ν„΄μŠ€ λ³€μˆ˜) μΆ”κ°€
    Direction(int value) {this.value = value;}
    
    public int getValue() {return value;}
}

ν•„μš”μ— 따라 ν•˜λ‚˜μ˜ μ—΄κ±°ν˜• μƒμˆ˜μ— μ—¬λŸ¬ 값을 지정할 수 μžˆλ‹€.
이에 맞게 μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ™€ μƒμ„±μž 등을 μƒˆλ‘œ μΆ”κ°€ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.

enum Direction {
    EAST(1, ">"), SOUTH(5, "V"), WEST(-1, "<"), NORTH(10, "^");
    
    private final int value; // μ •μˆ˜λ₯Ό μ €μž₯ν•  ν•„λ“œ(μΈμŠ€ν„΄μŠ€ λ³€μˆ˜) μΆ”κ°€
    private final String symbol;
    Direction(int value, String symbol) {
        this.value = value;
        this.symbol = symbol;
    }
    
    public int getValue() {return value;}
    public String getSymbol() {return symbol;}

Example

enum Direction { 
    EAST(1, ">"), SOUTH(2,"V"), WEST(3, "<"), NORTH(4,"^");

    private static final Direction[] DIR_ARR = Direction.values();
    private final int value;
    private final String symbol;

    Direction(int value, String symbol) { // private Direction(int value)
        this.value  = value;
        this.symbol = symbol;
    }

    public int getValue()      { return value;  }
    public String getSymbol()  { return symbol; }

    public static Direction of(int dir) {
        if (dir < 1 || dir > 4) {
            throw new IllegalArgumentException("Invalid value :" + dir);
        }
        return DIR_ARR[dir - 1];		
    }	

    // λ°©ν–₯을 νšŒμ „μ‹œν‚€λŠ” λ©”μ„œλ“œ. num의 κ°’λ§ŒνΌ 90도씩 μ‹œκ³„λ°©ν–₯으둜 νšŒμ „ν•œλ‹€.
    public Direction rotate(int num) {
        num = num % 4;

        if(num < 0) num +=4; // num이 음수일 λ•ŒλŠ” μ‹œκ³„λ°˜λŒ€ λ°©ν–₯으둜 νšŒμ „ 

        return DIR_ARR[(value-1+num) % 4];
    }

    public String toString() {
        return name()+getSymbol();
    }
} // enum Direction

class EnumEx2 {
    public static void main(String[] args) {
        for(Direction d : Direction.values()) 
            System.out.printf("%s=%d%n", d.name(), d.getValue()); 

        Direction d1 = Direction.EAST;
        Direction d2 = Direction.of(1);

        System.out.printf("d1=%s, %d%n", d1.name(), d1.getValue());
        System.out.printf("d2=%s, %d%n", d2.name(), d2.getValue());

        System.out.println(Direction.EAST.rotate(1));
        System.out.println(Direction.EAST.rotate(2));
        System.out.println(Direction.EAST.rotate(-1));
        System.out.println(Direction.EAST.rotate(-2));
    }
}

μ—΄κ±°ν˜•μ— 좔상 λ©”μ„œλ“œ μΆ”κ°€ν•˜κΈ°

Example

enum Transportation { 
    BUS(100)      { int fare(int distance) { return distance*BASIC_FARE;}},
    TRAIN(150)    { int fare(int distance) { return distance*BASIC_FARE;}},
    SHIP(100)     { int fare(int distance) { return distance*BASIC_FARE;}},
    AIRPLANE(300) { int fare(int distance) { return distance*BASIC_FARE;}};

    protected final int BASIC_FARE; // protected둜 ν•΄μ•Ό 각 μƒμˆ˜μ—μ„œ μ ‘κ·Όκ°€λŠ₯
	
    Transportation(int basicFare) { // private Transportation(int basicFare) {
		BASIC_FARE = basicFare;
	}

    public int getBasicFare() { return BASIC_FARE; }

    abstract int fare(int distance); // 거리에 λ”°λ₯Έ μš”κΈˆ 계산
}

class EnumEx3 {
    public static void main(String[] args) {
        System.out.println("bus fare="     +Transportation.BUS.fare(100));
        System.out.println("train fare="   +Transportation.TRAIN.fare(100));
        System.out.println("ship fare="    +Transportation.SHIP.fare(100));
        System.out.println("airplane fare="+Transportation.AIRPLANE.fare(100));
    }
}

Transportation은 μš΄μ†‘ μˆ˜λ‹¨μ˜ μ’…λ₯˜ λ³„λ‘œ μƒμˆ˜λ₯Ό μ •μ˜ν•˜κ³  있고,
각 μš΄μ†‘ μˆ˜λ‹¨μ—λŠ” κΈ°λ³Έμš”κΈˆμ΄ μ±…μ •λ˜μ–΄ μžˆλ‹€.
μ—¬κΈ°μ„œ 거리에 따라 μš”κΈˆμ„ κ³„μ‚°ν•˜λŠ” 방식이 각 μš΄μ†‘ μˆ˜λ‹¨λ§ˆλ‹€ λ‹€λ₯Έ 경우λ₯Ό μœ„ν•΄,
좔상 λ©”μ„œλ“œ fare(int distance)λ₯Ό μ„ μ–Έν•΄ 각 μ—΄κ±°ν˜• μƒμˆ˜κ°€ 이 좔상 λ©”μ„œλ“œλ₯Ό λ°˜λ“œμ‹œ κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€.

μ—΄κ±°ν˜•μ— 좔상 λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•  일은 그리 λ§Žμ§€ μ•Šλ‹€.

μ—΄κ±°ν˜•μ˜ 비ꡐ

enum Direction { EAST, SOUTH, WEST, NORTH; }

이 μ—΄κ±°ν˜• μƒμˆ˜ ν•˜λ‚˜ν•˜λ‚˜κ°€ Direction 객체이닀.
Direction 클래슀의 static μƒμˆ˜ EAST, SOUTH, WEST, NORTH의 값은 객체의 μ£Όμ†Œμ΄κ³ ,
이 값은 λ°”λ€Œμ§€ μ•ŠλŠ” κ°’μ΄λ―€λ‘œ ==둜 비ꡐ가 κ°€λŠ₯ν•˜λ‹€.

Example

abstract class MyEnum<T extends MyEnum<T>> implements Comparable<T> {
    static int id = 0;
		
    int ordinal;
    String name = "";

    public int ordinal() { return ordinal; }
	
    MyEnum(String name) {
        this.name = name;
        ordinal = id++;	
    }

    public int compareTo(T t) {
        return ordinal - t.ordinal();
    }
}

객체가 생성될 λ•Œλ§ˆλ‹€ 번호λ₯Ό λΆ™μ—¬μ„œ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜ ordinal에 μ €μž₯ν•œλ‹€.
그리고 Comparable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄μ„œ μ—΄κ±°ν˜• μƒμˆ˜κ°„μ˜ 비ꡐ가 κ°€λŠ₯ν•˜λ„λ‘ λ˜μ–΄ μžˆλ‹€.

만일 클래슀λ₯Ό MyEnum<T>와 같이 μ„ μ–Έν•˜μ˜€λ‹€λ©΄, compareTo()λ₯Ό μœ„μ™€ 같이
κ°„λ‹¨νžˆ μž‘μ„±ν•  수 μ—†μ—ˆμ„ 것이닀.
νƒ€μž… T에 ordinal()이 μ •μ˜λ˜μ–΄ μžˆλŠ”μ§€ 확인할 수 μ—†κΈ° λ•Œλ¬Έμ΄λ‹€.
κ·Έλž˜μ„œ MyEnum<T extends<MyEnum<T>>와 같이 μ„ μ–Έν•œ 것이며,
이것은 νƒ€μž… Tκ°€ MyEnum<T>의 μžμ†μ΄μ–΄μ•Ό ν•œλ‹€λŠ” μ˜λ―Έμ΄λ‹€.
νƒ€μž… Tκ°€ MyEnum의 μžμ†μ΄λ―€λ‘œ ordinal()이 μ •μ˜λ˜μ–΄ μžˆλŠ” 것은 λΆ„λͺ…ν•˜λ―€λ‘œ,
ν˜•λ³€ν™˜ 없이도 μ—λŸ¬κ°€ λ‚˜μ§€ μ•ŠλŠ”λ‹€.

그리고 좔상 λ©”μ„œλ“œλ₯Ό μƒˆλ‘œ μΆ”κ°€ν•˜λ©΄, 클래슀 μ•žμ—λ„ abstractλ₯Ό λΆ™μ—¬μ€˜μ•Ό ν•˜κ³ ,
각 static μƒμˆ˜λ“€λ„ 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.

참고 자료