接上回的单例模式线程是否安全?
https://blog.csdn.net/weixin_45262118/article/details/108519818
咱们先来谈谈枚举
枚举是JDK1.5推出的新特性,自己也是一个class类
java
咱们先建立一个枚举安全
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 方法的源码得知 枚举没法经过反射建立对象
spa
枚举没法用反射建立对象 咱们测试一下
.net
咱们尝试经过反射枚举的无参构造建立来建立对象线程
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
一样的方法经过反射来建立对象
3d
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); }
终于获得了预期的异常!!也就证实了不能经过反射来破坏枚举单例模式!
code