enum?

Enum?

enum은 열거된 상수의 집합을 나타내는 키워드입니다. 이런 enum을 사용해서 미리 상수를 정해놓고, 보통 코드상에서 switch-case 구문의 인자로 받아 타입에 따른 동작을 하도록 사용을 했습니다.

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
public enum Day {
	MONDAY,
    TUESDAY,
    WEDNESDAY,
    ...;
}

public class EnumExample {

		...
               
        switch (day) {
        case MONDAY:
            log.debug("월요일 입니다.");
            break;
        case TUESDAY:
            log.debug("화요일 입니다.");
            break;
        case WEDNESDAY:
            log.debug("수요일 입니다.");
            break;
            
            /*
             * ... 생략 ...
             */
        }
    }
}


enum 상수에 데이터를 넣으려면 final로 멤버변수를 선언하고 데이터를 그 필드에 넣어주는 생성자를 만들어 데이터를 저장하면 됩니다. enum은 변경 불가능한 상수여야 하므로 반드시 final로 그 값을 할당해야 합니다.

1
2
3
4
5
6
7
8
9
10
public enum ErrorType {
	ERROR_ONE("this is error type one"),
    ERROR_TWO("this is error type two");
	
	private final String errorDescription;

	ErrorType(String errorDescription) {
    	this.errorDescription = errorDescription;
    }
}


이런 enum의 사용 이외에도 상수값 자체에 함수를 정의하여 사용할 수도 있습니다. 함수를 정의하고 외부에서 사용할 경우에는 enum 내부에서 abstract로 선언해야 합니다.

1
2
3
4
5
6
public enum ErrorType {
	ERROR_ONE { public String getErrorMessage() {return "this is error type one.";} },
    ERROR_TWO { public String getErrorMessage() {return "this is error type two.";} };
    
    public abstract String getErrorMessage();    
}

당연히 상수와 함수를 동시에 사용할 수도 있습니다.

1
2
3
ERROR_ONE("error one") {
	public String getErrorMessage() {return "this is error type one."}
}


그러나 이렇게 구현하는 방법은 상수별 메소드간의 데이터 공유가 어렵게 합니다. 만약 데이터를 공유해야 할 필요가 없다면 상관없지만 필요한 경우라면 아래처럼 내부에 private enum을 생성하고 enum의 생성자로 private enum을 받아 사용할 수 있습니다.

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
32
33
34
35
enum PayrollDay {
    MONDAY (PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY),
    WEDNEDAY(PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY),
    FRIDAY(PayType.WEEKDAY), 
    SATURDAY(PayType.WEEKEND), SUNDAY(PayType.WEEKEND);

    private final PayType payType;
    PayrollDay(PayType payType) { this.payType = payType; }

    double pay(double hoursWorked, double payRate) {
         return payType.pay(hoursWorked, payRate);
    }

    private enum PayType {
        WEEKDAY {
            double overtimePay(double hours, double payRate) {
                return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT) * payRate / 2;
            }
        },
        WEEKEND {
            double overtimePay(double hours, double payRate) {
                return hours * payRate / 2;
            }
        };

        private static final int HOURS_PER_SHIFT = 8;

        abstract double overtimePay(double hrs, double payRate);

        double pay(double hoursWorked, double payRate) {
            double basePay = hoursWorked * payRate;
            return basePay + overtimePay(hoursWorked, payRate);
        }
    }
}

참고 : 서경원의 블로그