虽然单例模式的构造器私有化,但通过反射和反序列化依然可以获得新的对象 (枚举由于是有JVM底层实现,反射和反序列化无法破解)。
1、反射破解单例模式,及其对策:
package com.chen.Crack_Singleton; /** * 饿汉式单例模式 * @author Administrator * */ public class SingletonDemo01 { // 2、创建对象 private static SingletonDemo01 instance = new SingletonDemo01(); // 1、私有化构造器 private SingletonDemo01() { /* * 添加过后就可以防止利用反射来破解单例模式 if(instance != null) { throw new RuntimeException(); } */ } // 3、提供静态方法获得实例对象 public static SingletonDemo01 getInstance() { return instance; } }package com.chen.Crack_Singleton; import java.lang.reflect.Constructor; /** * 利用反射来破解单例模式(枚举类型实现单例模式除外) * @author Administrator * */ public class TestDemo01 { public static void main(String[] args) throws Exception { SingletonDemo01 instance = SingletonDemo01.getInstance(); SingletonDemo01 instance2 = SingletonDemo01.getInstance(); System.out.println(instance); System.out.println(instance2); // 利用反射来破解单例模式 Class<SingletonDemo01> clazz = (Class<SingletonDemo01>) Class.forName("com.chen.Crack_Singleton.SingletonDemo01"); Constructor<SingletonDemo01> c = clazz.getDeclaredConstructor(null); c.setAccessible(true); SingletonDemo01 instance3 = c.newInstance(); SingletonDemo01 instance4 = c.newInstance(); // 这两个对象与instance 和 instance2就不同乐,单例模式被破解 System.out.println(instance3); System.out.println(instance4); } }
2、反序列化破解单例模式及其对策
package com.chen.Crack_Singleton; import java.io.Serializable; /** * 懒汉式实现单例模式 * @author Administrator * */ public class SingletonDemo02 implements Serializable{ private static SingletonDemo02 instance; private SingletonDemo02() { } public static synchronized SingletonDemo02 getInstance() { if(instance == null) { instance = new SingletonDemo02(); } return instance; } // 添加一个方法,避免反序列化时的漏洞 // readResolve是一个回调方法,表示在反序列化时,直接返回指定对象,不需要在创建新对象 private Object readResolve() { return instance; } }package com.chen.Crack_Singleton; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; /** * 利用反序列化来破解单列模式 * @author Administrator * */ public class TestDemo02 { public static void main(String[] args) throws Exception { SingletonDemo02 instance = SingletonDemo02.getInstance(); SingletonDemo02 instance2 = SingletonDemo02.getInstance(); System.out.println(instance); System.out.println(instance2); // 利用反序列化来破解单例模式 // 序列化操作 OutputStream os = new FileOutputStream("F:/New/a.txt"); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(instance); oos.flush(); oos.close(); os.close(); // 反序列化操作 InputStream is = new FileInputStream("F:/New/a.txt"); ObjectInputStream ois = new ObjectInputStream(is); SingletonDemo02 instance3 = (SingletonDemo02) ois.readObject(); System.out.println(instance3);// 与instance不同 } }
1万+

被折叠的 条评论
为什么被折叠?



