單例能夠用枚舉類來實現,且線程安全。那麼,爲何它就是線程安全的呢? 設計一個枚舉類Day.java
文件,以下:java
//定義枚舉類型 public enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
執行以下命令:安全
javac Day.java
, 生成 Day.class
。ide
直接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類型
是線程安全的。對象
枚舉類型在序列化的時候Java僅僅是將枚舉對象的name屬性輸出到結果中,反序列化的時候則是經過java.lang.Enum的valueOf方法來根據名字查找枚舉對象
參考地址: 深度分析 Java 的枚舉類型:枚舉的線程安全性及序列化問題 - 方丈的博客 - CSDN博客
插件名:asm bytecode outline
如上圖所示操做,便可顯示出如上圖右側的反編譯後的代碼。