Effective Java

《Effective Java》


6. enum & annotation

6.1 enum basics

int枚举模式 -> String枚举模式 -> enum枚举模式

    1. Java的枚举本质上是int值
    1. Java枚举类型是通过公有的static final域为每个枚举常量导出实例类
    1. 因为没有可以访问的构造器, 所以枚举类型是真正的final
    1. 单元素枚举类型已经成为实现singleton的最佳方法, 它更简洁, 并且无偿提供了序列化机制, 绝对防止多次序列化
    1. 枚举类型是实例受控的, 它是singleton的泛型化, singleton本质上是单元素的枚举.

6.2 Constant-specific method implementaton(特定于常量的方法实现)

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
36
37
38
39
40
41
42
43
44
public enum Operation {

PLUS("+") {
double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
double apply(double x, double y) {
return x - y;
}
},
TIMES("*") {
double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
double apply(double x, double y) {
return x / y;
}
};
private final String symbol;

@Override
public String toString() {
return symbol;
}
//默认是private, 且不能为protected和public
Operation(String sym) {
this.symbol = sym;
}

abstract double apply(double x, double y);
}

public class Test {
public static void main(String[] ar) {
double x = 2, y = 5;
for (Operation op : Operation.values()) {
System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}
}
}

6.3 Strategy 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
36
37
38
39
40
41
42
43
44
/***策略枚举模式****/
public enum PayrollDay {
MONDAY(PayType.WEEKDAY),
TUESDAY(PayType.WEEKDAY),
WEDNESDAY(PayType.WEEKDAY),
THURSDAY(PayType.WEEKDAY),
FRIDAY(PayType.WEEKDAY),
SATURDAY(PayType.WEEKEND),
SUNDAY(PayType.WEEKEND);

private final PayType payType;

PayrollDay(PayType type) {
this.payType = type;
}

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


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

private static final int HOURS_PER_SHIFT = 8;

abstract double overtimePay(double hrs, double payRate);

double pay(double workedHour, double payRate) {
return workedHour * payRate + overtimePay(workedHour, payRate);
}
}
}