参考文章 https://blog.csdn.net/javazejian/article/details/71333103
参考书籍 effective java》
原理阐述
使用关键字enum创建枚举类型并编译后,编译器会为我们生成一个类,这个类继承了Java API中的java.lang.Enum类。
这个类继承了Java API中的java.lang.Enum类,编译器会自动添加方法、生成枚举实例。
整体的感受是,编译器做了这样的事情: 建造单例枚举值,用数组来容纳这些枚举值。
常见用法
1.常量
2.switch
3.实现接口
4.接口组合枚举
5.定义抽象方法
6.单例模式
7.枚举集合EnumSet和EnumMap
代码演示
- 演示枚举原理
比如一个java class是这样
enum PeriodApply {
APPLY_INPROCESS("1", "申请中"),
APPLY_FAILED("2", "申请失败"),
APPLY_SUCCESSFULLY("3", "申请成功"),
;
private String code;
private String desc;
PeriodApply(String code, String desc) {
this.code = code;
this.desc = desc;
}
}
编译过后的代码其实是这样:
final class PeriodPay extends Enum {
private PeriodPay(String s, int i, String code, String desc)
{
super(s, i);
this.code = code;
this.desc = desc;
}
public static final PeriodPay PAY_INPROCESS;
public static final PeriodPay PAY_FAILED;
public static final PeriodPay PAY_SUCCESSFULLY;
private String code;
private String desc;
static
{
PAY_INPROCESS = new PeriodPay("PAY_INPROCESS", 0, "1", "申请中");
PAY_FAILED = new PeriodPay("PAY_FAILED", 1, "2", "申请失败");
PAY_SUCCESSFULLY = new PeriodPay("PAY_SUCCESSFULLY", 2, "2", "申请成功");
}
}
- 演示接口组合枚举1
public enum EnumMeal {
APPETIZER(Food.Appetizer.class),
MAINCOURSE(Food.MainCourse.class),
;
private Food[] values;
private EnumMeal(Class extends Food> kind) {
//通过class对象获取枚举实例
values = kind.getEnumConstants();
}
public Food[] getValues() {
return values;
}
public void setValues(Food[] values) {
this.values = values;
}
public static void main(String[] args) {
System.out.println("开胃菜:" + Arrays.toString(APPETIZER.getValues()));
}
public interface Food {
enum Appetizer implements Food {
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOO;
}
}
}
- 演示接口组合枚举2
场景:
申请状态的枚举,A业务和B业务关心的枚举粗细程度不一样,A关心申请失败或成功,B不仅关心成功失败,还要关心是因为什么原因失败。
名称 | 申请中 | 申请成功 | 申请失败 |
---|---|---|---|
A业务 | 申请中 | 申请成功 | 申请失败 |
B业务 | 上级领导已审批 CTO已审批 |
申请成功 | 上级领导驳回失败 CTO驳回失败 |
上级领导已审批 和 CTO已审批 都是属于申请中的状态,
上级领导驳回失败 和 CTO驳回失败 都是属于申请失败的状态
将所有情况列在同一个枚举类中,枚举中增加新的标志PeriodI,来表明枚举值的分类。
public enum EnumBH {
APPLY_LEADER_PASS("101", "上级领导已审批", PeriodApply.APPLY_INPROCESS),
APPLY_CTO_PASS("102", "CTO已审批", PeriodApply.APPLY_INPROCESS),
APPLY_LEADER_REJECT("200", "上级领导驳回失败", PeriodApply.APPLY_FAILED),
APPLY_CTO_REJECT("201", "CTO驳回失败", PeriodApply.APPLY_FAILED),
APPLY_SUCCESSFULLY("300", "申请成功", PeriodApply.APPLY_SUCCESSFULLY),
PAY_CONFIRMING("300", "收款方确认中", PeriodPay.PAY_INPROCESS),
PAY_CC_NOT_ENOUGH("300", "信用卡额度不足", PeriodPay.PAY_FAILED),
PAY_BC_NOT_ENOUGH("300", "银行卡余额不足", PeriodPay.PAY_FAILED),
PAY_SUCCESSFULLY("300", "支付成功", PeriodPay.PAY_SUCCESSFULLY),
;
private String code;
private String desc;
private PeriodI periodI;
EnumBH(String code, String desc, PeriodI periodI) {
this.code = code;
this.desc = desc;
this.periodI = periodI;
}
}
interface PeriodI {
}
enum PeriodPay implements PeriodI {
PAY_INPROCESS("1", "支付中"),
PAY_FAILED("2", "支付失败"),
PAY_SUCCESSFULLY("2", "支付成功"),
;
}
enum PeriodApply implements PeriodI {
APPLY_INPROCESS("1", "申请中"),
APPLY_FAILED("2", "申请失败"),
APPLY_SUCCESSFULLY("3", "申请成功"),
;
}