单例模式的漏洞
我们实现单例模式可以有5种实现方式,分别是 懒汉式、饿汉式、双重锁模式、枚举模式、静态内部类模式,但是呢,由于双重锁和JMM结构不一致吗,一般不推荐使用,但是其他的除了枚举模式以外,其他的都可被攻破!
反射攻击模式
1 | //1.通过反射攻破单例模式 |
最后打印出的结果是false。也就是创建了不同的对象,即打破了单例模式。
那么如何补救呢,可以这样,构建方法内判断对象存在后再决定是否创建
1 | public class SingletonDemo1 { |
序列化反序列化方式
我们可以结合对象字节流的操作,将字节流先存储在文件中,然后读取,会创建一个不一样的对象1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28//2.通过序列化攻破单例模式
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
ObjectInputStream objectInputStream = null;
FileInputStream fileInputStream = null;
try {
SingletonDemo2 singletonDemo2 = SingletonDemo2.getInstance();
System.out.println("开始");
System.out.println(singletonDemo2);
fileOutputStream = new FileOutputStream("D:/test.txt");
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(singletonDemo2);
fileInputStream = new FileInputStream("D:/test.txt");
objectInputStream = new ObjectInputStream(fileInputStream);
SingletonDemo2 demo2 = (SingletonDemo2) objectInputStream.readObject();
System.out.println("结束");
System.out.println(demo2);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
fileInputStream.close();
objectInputStream.close();
objectOutputStream.close();
fileOutputStream.close();
}
结果demo2和singletonDemo2的地址不相同,表示没有遵守单例模式
我们如何避免呢
在相应的类中加上此方法即可
以后学习中,继续总结,走起…