Enum枚举类的理解

枚举类的一个用处就是作为常量存储方式之一,如下:
Enum枚举类的理解_第1张图片
那么在底层,枚举类是如何实现的呢?
我们通过 java -verbose 工具查看该类如下:

在这里插入图片描述
一个final类继承java.lang.Enum,因此知道枚举类是不能被继承的
2.
Enum枚举类的理解_第2张图片
我们可以看到我们自定义的枚举类中的属性在底层其实也是static final的常量,不过在这里还没有初始化
3.
Enum枚举类的理解_第3张图片
其中putstatic字节码:为指定的类的静态域赋值,这里就是为刚才的常量赋值了。

看到这儿我们就知道Enum为什么线程安全了,它也是利用了 ClassLoader的线程安全机制(static属性由类加载器加载)

当然,这并不是枚举作为单例模式最佳实现方式的最有力的理由

所以这里还有一个问题:Enum会不会像其他普通类一样——即使我在类中实现单例,但我仍可通过反序列化暴力生成一个新的对象呢?

Enum枚举类的理解_第4张图片
结果是true

结论:前后仍然是同一个对象,这是为什么呢?

在序列化的时候Java仅仅是将枚举对象的name属性输出到结果中,反序列化的时候则是通过java.lang.Enum的valueOf方法来根据名字查找枚举对象。同时,编译器是不允许任何对这种序列化机制的定制的,因此禁用了writeObject、readObjectNoData、writeReplace和readResolve等方法。
Enum枚举类的理解_第5张图片
Enum枚举类的理解_第6张图片
那么,既然枚举类禁用了序列化方法,那么只有从ObjectInputSteam和ObjectOutputStream中找了:

就是这么调用的valueof方法

总结:

  • 线程安全
  • 不会被序列化暴力破坏单例特性

你可能感兴趣的:(Java)