单例模式是否真的线程安全之----枚举-鸿蒙开发者社区-51CTO.COM

单例模式是否真的线程安全之----枚举

killads
发布于 2020-9-21 11:10
浏览
0收藏

接上回的单例模式线程是否安全?
https://harmonyos.51cto.com/posts/871

我们先来谈谈枚举

枚举是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);

    }

 

单例模式是否真的线程安全之----枚举-鸿蒙开发者社区

 

终于得到了预期的异常!!也就证明了不能通过反射来破坏枚举单例模式!

 

 

 

作者:____小明同学i

来源:CSDN

分类
已于2020-9-22 10:30:14修改
收藏
回复
举报
回复
    相关推荐