JAVA中枚举类型(Enum)的本质
JAVA中提供了枚举这种类型,枚举类型可以取代以往常量的定义方式,即将常量封装在类或接口中。此外,枚举类型还提供了安全检查功能。
在以前学习单例设计模式时,可以使用枚举来实现单例模式。那么枚举的本质是什么呢?
枚举在单例模式中的使用:
public enum SingleEnum { INSTANCE; SingleEnum() { System.out.println("init SingleEnum"); } public static void staticMethod() { System.out.println("static method"); } }
枚举单例在多线程环境的测试:
public class SingleEnumTest { @Test public void values() { for (int i = 0; i < 10; i++) { new Thread(() -> { System.out.println(SingleEnum.INSTANCE.hashCode()); }).start(); } } }
测试结果:
init SingleEnum 548807905 548807905 548807905 548807905 548807905 548807905 548807905 548807905 548807905 548807905
测试发现,SingleEnum是线程安全的单例。
那么Enum为什么可以天然支持单例?
使用javac命令编译SingleEnum.java,再使用javap命令查看java编译器为我们生成的SingleEnum的字节码。
通过这个我们可以发现,枚举类在编译过之后,其实是final class,原Enum中的枚举值是作为public staic final xxx静态常量值存在的,在类加载时生产了唯一的实例,并且由JVM天然的保证了线程的安全性。
结论:枚举类型最终还是以类的形式存在,枚举类中的枚举值是以类的静态常量的方式存在。