文章目录
-
- [4.3 单例模式存在的问题](#4.3 单例模式存在的问题)
-
- 4.3.1序列化反序列化破环单例模式
- [4.3.2 反射破环单例模式](#4.3.2 反射破环单例模式)
4.3 单例模式存在的问题
破坏单例模式:
使上面定义的单例类(Singleton)可以创建多个对象,枚举方式除外。有两种方式,分别是序列化反序列化和反射来破坏单列模式。
4.3.1序列化反序列化破环单例模式
序列化反序列化破环单例模式
java
// 懒汉式-方式4(静态内部类方式)
//序列化反序列化破环单例模式
public class Singleton implements Serializable {
// 私有构造方法不让外界创建本类的对象
private Singleton(){};
// 定义静态内部类 实现单例模式
private static class SingletonHolder{
// 在内部类中声明并初始化外部类的对象
// 在内部类中声明并初始化外部类的对象
//static:保证只创建一次,final:防止外界对其修改
private static Singleton INSTANCE = new Singleton();
}
// 提供对外公共的访问方式
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
===========================================================
public class Test {
public static void main(String[] args) throws Exception{
//序列化反序列化破环单例模式
//往文件中写对象
// writeObjFile();
//从文件中读取对象
Singleton instance1 = readObjFile();
Singleton instance2 = readObjFile();
// singleton.demo8.Singleton@3b9a45b3
System.out.println(instance1);
// singleton.demo8.Singleton@7699a589
System.out.println(instance2);
boolean b = instance1 == instance2;
System.out.println(b);//false
//false说明创建的是两个Singleton类的对象,违背了单一规则
}
// 定义方法,将对象写出到文件中----序列化
public static void writeObjFile() throws IOException {
//获取Singleton类的对象
Singleton instance = Singleton.getInstance();
//创建对象输出流
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("pattern\\file\\1.txt"));
//将instance对象写出到文件中
oos.writeObject(instance);
}
// 定义方法,将文件中的序列化对象进行反序列化读入
public static Singleton readObjFile() throws Exception{
//创建输入流对象
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("pattern\\file\\1.txt"));
//第一个读取Singleton对象
Singleton instance = (Singleton) ois.readObject();
return instance;
}
// main end.....
}
4.3.2 反射破环单例模式
java
// 懒汉式-方式4(静态内部类方式)
//反射破环单例模式
public class Singleton {
// 私有构造方法不让外界创建本类的对象
private Singleton (){}
// 定义静态内部类
private static class SingletonHolder{
// 在内部类中声明并初始化外部类的对象
// 在内部类中声明并初始化外部类的对象
//static:保证只创建一次,final:防止外界对其修改
private static final Singleton INSTANCE = new Singleton();
}
// 提供对外公共的访问方式
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
============================================================
public class Test {
public static void main(String[] args) throws Exception {
//1. 获取Singleton类的字节码文件
Class<Singleton> aClass = Singleton.class;
//2. 获取空参构造方法
Constructor cons = aClass.getDeclaredConstructor();
// 3.因为空参构造是私有的,所以要取消访问检查才能创建对象
cons.setAccessible(true);
// 4.创建Singleton对象
Singleton instance1 = cons.newInstance();
Singleton instance2 = cons.newInstance();
boolean b = instance1 == instance2;
System.out.println(b);//false
//false说明创建的是两个Singleton类的对象,违背了单一规则
}
}