单例模式,反射破环? (2)

单例模式,反射破环?

结论:反射可以破坏这种单例

解决

// 懒汉式单例 public class LazyMan { private LazyMan(){ synchronized (LazyMan.class){ if (lazyMan!=null){ throw new RuntimeException("不要试图使用反射破环 异常"); } } System.out.println(Thread.currentThread().getName()+":: ok"); } private volatile static LazyMan lazyMan; // 双重检测锁模式的 懒汉式单例 DCL懒汉式 public static LazyMan getInstance(){ if (lazyMan==null){ synchronized (LazyMan.class){ if (lazyMan==null){ lazyMan = new LazyMan(); //不是一个原子性操作 } } } return lazyMan; } //反射 public static void main(String[] args) throws Exception { LazyMan instance1 = LazyMan.getInstance(); Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null); declaredConstructor.setAccessible(true); // 无视了私有的构造器 // 通过反射创建对象 LazyMan instance2 = declaredConstructor.newInstance(); System.out.println(instance1); System.out.println(instance2); } }

单例模式,反射破环?

但是如果都用反射创建对象的情况下,还是会破环单例!

测试

单例模式,反射破环?

解决

// 懒汉式单例 public class LazyMan { private static boolean abc = false; private LazyMan(){ synchronized (LazyMan.class){ if (abc==false){ abc=true; }else { throw new RuntimeException("不要试图使用反射破环 异常"); } } System.out.println(Thread.currentThread().getName()+":: ok"); } private volatile static LazyMan lazyMan; // 双重检测锁模式的 懒汉式单例 DCL懒汉式 public static LazyMan getInstance(){ if (lazyMan==null){ synchronized (LazyMan.class){ if (lazyMan==null){ lazyMan = new LazyMan(); //不是一个原子性操作 } } } return lazyMan; } //反射 public static void main(String[] args) throws Exception { //LazyMan instance1 = LazyMan.getInstance(); Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null); declaredConstructor.setAccessible(true); // 无视了私有的构造器 // 通过反射创建对象 LazyMan instance2 = declaredConstructor.newInstance(); LazyMan instance1 = declaredConstructor.newInstance(); System.out.println(instance1); System.out.println(instance2); } }

单例模式,反射破环?

但是如果被人知道 abc这个变量,也可以破环!

单例模式,反射破环?

单例又被破环了!

看一下源码

单例模式,反射破环?

它说不能使用反射破环枚举,枚举是jdk1.5出现的,自带单例模式!

测试,写一个枚举类

// enum 本身就是一个class类 public enum EnumSingle { INSTANCE; public EnumSingle getInstance(){ return INSTANCE; } }

查看它的源码

单例模式,反射破环?

试图破环!

// enum 本身就是一个class类 public enum EnumSingle { INSTANCE; public EnumSingle getInstance(){ return INSTANCE; } } class Test{ public static void main(String[] args) throws Exception { EnumSingle instance1 = EnumSingle.INSTANCE; Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(null); declaredConstructor.setAccessible(true); EnumSingle instance2 = declaredConstructor.newInstance(); System.out.println(instance1); System.out.println(instance2); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyxwyd.html