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天然的保证了线程的安全性。

结论:枚举类型最终还是以类的形式存在,枚举类中的枚举值是以类的静态常量的方式存在。

经验分享 程序员 微信小程序 职场和发展