enum枚举类为何线程安全-附字节码查看方式

单例能够用枚举类来实现,且线程安全。那么,为何它就是线程安全的呢? 设计一个枚举类Day.java文件,以下:java

//定义枚举类型
public enum Day {
    MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

执行以下命令:安全

javac Day.java, 生成 Day.classide

直接cat 查看该class文件的话,会发现其乱码。idea

反编译该class文件: javap -c Day.class.net

结果以下:插件

public final class Day extends java.lang.Enum<Day> {
  public static final Day MONDAY;

  public static final Day TUESDAY;

  public static final Day WEDNESDAY;

  public static final Day THURSDAY;

  public static final Day FRIDAY;

  public static final Day SATURDAY;

  public static final Day SUNDAY;

  public static Day[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[LDay;
       3: invokevirtual #2                  // Method "[LDay;".clone:()Ljava/lang/Object;
       6: checkcast     #3                  // class "[LDay;"
       9: areturn
	   
...(省略)

简要分析

该类Day.java 是继承了Enum类的,同时被final关键字修饰:这个类是不能被继承的。线程

同时,设计

static类型的属性会在类被加载以后被初始化,当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的code

因此,建立一个enum类型是线程安全的。对象

扩展

为何说enum在序列化、反序列化的时候特殊性

枚举类型在序列化的时候Java仅仅是将枚举对象的name属性输出到结果中,反序列化的时候则是经过java.lang.Enum的valueOf方法来根据名字查找枚举对象

参考地址: 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题 - 方丈的博客 - CSDN博客

idea 反编译插件

插件名:asm bytecode outline

如上图所示操做,便可显示出如上图右侧的反编译后的代码。

相关文章
相关标签/搜索