反序列化破坏单例模式:
/**
* 反序列化破坏单例模式
*/
public class DeserializedBreakSingleton {
@Test
public void test(){
//通过单例模式获取对象
DoubleIfSynchronizedSingleton singleton = DoubleIfSynchronizedSingleton.getSingleton();
//通过反序列化获取对象
DoubleIfSynchronizedSingleton deserializedSingleton = DeserializedBreakSingleton.getSerializedSingleton(singleton);
System.out.println("hashCode of singleton:"+singleton);
System.out.println("hashCode of deserializedSingleton:"+deserializedSingleton);
System.out.println(singleton == deserializedSingleton);
}
/**
* 通过序列化获取单例对象
*/
private static DoubleIfSynchronizedSingleton getSerializedSingleton(DoubleIfSynchronizedSingleton singleton){
File file = new File("singleton");
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
DoubleIfSynchronizedSingleton newSingleton = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(singleton);
oos.flush();
ois = new ObjectInputStream(new FileInputStream(file));
newSingleton = (DoubleIfSynchronizedSingleton) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}finally {
if (ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (oos != null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(file.exists()){
file.delete();
}
}
return newSingleton;
}
}
/**
* 双重检测锁的单例模式
*/
class DoubleIfSynchronizedSingleton implements Serializable {
private static final long serialVersionUID = 3288137447362611668L;
private static int count = 0; //创建对象次数
private volatile static DoubleIfSynchronizedSingleton singleton = null;
private DoubleIfSynchronizedSingleton() {
//解决反射破坏单例问题
synchronized (DoubleIfSynchronizedSingleton.class) {
if (count > 0){
throw new RuntimeException("你居然敢破坏我的单例.....");
}
count++;
}
}
/**
* 单例对象生成方法
* @return
*/
public static DoubleIfSynchronizedSingleton getSingleton() {
if (singleton == null) {
synchronized (DoubleIfSynchronizedSingleton.class) {
if (singleton == null) {
singleton = new DoubleIfSynchronizedSingleton();
}
}
}
return singleton;
}
}
执行结果:
hashCode of singleton:serialization.DoubleIfSynchronizedSingleton@1376c05c
hashCode of deserializedSingleton:serialization.DoubleIfSynchronizedSingleton@e2d56bf
false
hashCode和对象地址都不同,可以确定是两个对象,破坏了单例模式。
解决办法:
在单例类中添加readResolve方法即可。
/**
* 双重检测锁的单例模式
*/
class DoubleIfSynchronizedSingleton implements Serializable {
private static final long serialVersionUID = 3288137447362611668L;
private static int count = 0; //创建对象次数
private volatile static DoubleIfSynchronizedSingleton singleton = null;
private DoubleIfSynchronizedSingleton() {
//解决反射破坏单例问题
synchronized (DoubleIfSynchronizedSingleton.class) {
if (count > 0){
throw new RuntimeException("你居然敢破坏我的单例.....");
}
count++;
}
}
/**
* 单例对象生成方法
* @return
*/
public static DoubleIfSynchronizedSingleton getSingleton() {
if (singleton == null) {
synchronized (DoubleIfSynchronizedSingleton.class) {
if (singleton == null) {
singleton = new DoubleIfSynchronizedSingleton();
}
}
}
return singleton;
}
/**
* 解决反序列化破坏单例问题
*/
private Object readResolve(){
return singleton;
}
}
执行结果:
hashCode of singleton:serialization.DoubleIfSynchronizedSingleton@1376c05c
hashCode of deserializedSingleton:serialization.DoubleIfSynchronizedSingleton@1376c05c
true
可以看到,两种方式拿到的是同一个对象。
但是,我不知道为什么添加这个方法就可以解决反序列化破坏单例的问题,哪位大神可以帮忙说一下,感谢!!!