枚举

https://www.yuque.com/docs/share/d26ab24e-b3c7-41ba-b414-d2c7b0a3a633?#

概念

基本
枚举类型较传统定义常量的方式,除了具有参数类型检测的优势之外,还具有其他方面的优势。
用户可以将一个枚举类型看作是一个类,它继承于java.lang.Enum类,当定义一个枚举类型时,每一个枚举类型成员都可以看作是枚举类型的一个实例,这些枚举类型成员默认都被final、public、static所修饰,所以当使用枚举类型成员时直接使用枚举类型名称调用枚举类型成员即可。

1.优势


枚举类型声明提供了一种用户友好的变量定义方法,枚举了某种数据类型所有可能出现的值。总结枚举类型,它具有以下特点:

类型安全。
紧凑有效的数据定义。
可以和程序其他部分完美交互。
运行效率高。
提高代码可读性(使用的时候直接Week.Monday即可)

限制了某些东西的范围,举个栗子:一年四季,只能有春夏秋冬,你要是字符串表示的话,那就海了去了,但是,要用枚举类型的话,你在enum的大括号里面把所有的选项,全列出来,那么这个季节的属性,对应的值,只能在里面挑。不能有其他的。

2.使用场景

  1. 单例
    2. 有穷对象的集合
    3.常量
    4.switch
    5.向枚举中添加新的方法
    6.覆盖枚举的方法
    7.实现接口
    8.使用接口阻止枚举
    9.关于枚举集合的时候(没啥用)

    下面是详细介绍
    https://blog.csdn.net/qq_27093465/article/details/52180865

    3.枚举可解决线程安全问题

    (1)枚举中的各个枚举项通过static来定义的
    (2)static类型的属性会在类被加载之后被初始化
    (3)当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的(因为虚拟机在加载枚举的类的时候,会使用ClassLoader的loadClass方法,而这个方法使用同步代码块保证了线程安全)。所以,创建一个enum类型是线程安全的。

    4.枚举可解决反序列化会破坏单例的问题

    (1)普通的Java类的反序列化过程中,会通过反射调用类的默认构造函数来初始化对象
    (2)在序列化的时候Java仅仅是将枚举对象的name属性输出到结果中,反序列化的时候则是通过java.lang.Enum的valueOf方法来根据名字查找枚举对象。同时,编译器是不允许任何对这种序列化机制的定制的,因此禁用了writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法。

    5.枚举单例模式是如何防止反射攻击

    https://blog.csdn.net/liuyingming910/article/details/42457265

    http://www.cnblogs.com/chiclee/p/9097772.html

    简单说枚举是个抽象类,一旦一个类声明为枚举,实际上就是继承了Enum,在源码中反射在通过newInstance创建对象时,会检查该类是否Enum修饰,如果是就抛出异常,反射失败.

    6.EnumSet and EnumMap

    参考:
    https://www.yuque.com/docs/share/d26ab24e-b3c7-41ba-b414-d2c7b0a3a633?#

使用

循环遍历枚举

看下面的 getDesc 方法,这个就是循环遍历枚举

  1. @Getter
  2. @AllArgsConstructor
  3. public enum ScItemTypeEnum {
  4. /**
  5. * 普通货品
  6. */
  7. NORMAL(0, "普通"),
  8. /**
  9. * 组合货品
  10. */
  11. AGGREGATION(1, "组合");
  12. private int type;
  13. private String desc;
  14. /**
  15. * 根据type值获取描述信息
  16. *
  17. * @param type
  18. * @return
  19. */
  20. public static String getDesc(int type) {
  21. ScItemTypeEnum[] values = ScItemTypeEnum.values();
  22. for (ScItemTypeEnum value : values) {
  23. if (type == value.getType()) {
  24. return value.getDesc();
  25. }
  26. }
  27. return null;
  28. }
  29. }