接上回的單例模式執行緒是否安全?
https://blog.csdn.net/weixin_45262118/article/details/108519818
我們先來談談列舉
列舉是JDK1.5推出的新特性,本身也是一個class類
我們先創建一個列舉
public enum EnumTest {
INSTANCE; //寫一個就為單例
public EnumTest getInstance() {
return INSTANCE;
}
}
列舉是執行緒安全的嗎?直接上代碼測驗!
class SingleTest {
public static void main(String[] args) {
EnumTest instance1 = EnumTest.INSTANCE;
EnumTest instance2 = EnumTest.INSTANCE;
System.out.println(instance1);
System.out.println(instance2);
}
}

通過反射的 newInstance 方法的原始碼得知 列舉無法通過反射創建物件

列舉無法用反射創建物件 我們測驗一下


我們嘗試通過反射列舉的無參構造創建來創建物件
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
EnumTest instance1 = EnumTest.INSTANCE;
Constructor<EnumTest> declaredConstructor = EnumTest.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
EnumTest instance2 = declaredConstructor.newInstance();
System.out.println(instance1);
System.out.println(instance2);
}
運行 發現報錯了 但是看報的錯誤和我們預期的不一樣

并沒有報出 newInstance 中拋出的例外:
Cannot reflectively create enum objects
而是 拋出了 沒有這樣的方法 的例外

難道是IDEA騙了我們?為什么不是無參構造方法 拋出沒有這樣的方法的例外?

通過百度查閱資料得到下面的結論

可以在上圖中看出其實是有參構造的 而且引數是String 和 int
同樣的方法通過反射來創建物件
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
EnumTest instance1 = EnumTest.INSTANCE;
Constructor<EnumTest> declaredConstructor =
EnumTest.class.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
EnumTest instance2 = declaredConstructor.newInstance();
System.out.println(instance1);
System.out.println(instance2);
}

終于得到了預期的例外!!也就證明了不能通過反射來破壞列舉單例模式!
請點個贊再走!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/76223.html
標籤:其他
