将单例对象序列化和反序列化操作后得到的新对象与原单例对象并不相同,因为反序列化是通过反射获取的新对象。
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
HungrySingleton hungrySingleton = HungrySingleton.getInstance();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file"));
oos.writeObject(hungrySingleton);
File file = new File("singleton_file");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
HungrySingleton newHungrySingleton = (HungrySingleton) ois.readObject();
System.out.println(hungrySingleton);
System.out.println(newHungrySingleton);
System.out.println(hungrySingleton==newHungrySingleton);
}
}
输出结果:
designmodel.singleton.HungrySingleton@1d44bcfa
designmodel.singleton.HungrySingleton@b4c966a
false
但是可以通过在单例类中添加readResolve方法解决该问题,但是该单例类必须实现Serializable或Externalizable接口。
public class HungrySingleton implements Serializable {
private static final HungrySingleton hungrySingleton;
static {
hungrySingleton = new HungrySingleton();
}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
private Object readResolve(){
return hungrySingleton;
}
}
readResolve方法并不是重写Object类中的方法,具体实现的原理可从源码中得到解释。
/**
* Returns true if represented class is serializable or externalizable and
* defines a conformant readResolve method. Otherwise, returns false.
*/
boolean hasReadResolveMethod() {
requireInitialized();
return (readResolveMethod != null);
}
输出结果:
designmodel.singleton.HungrySingleton@1d44bcfa
designmodel.singleton.HungrySingleton@1d44bcfa
true
单例模式与序列化
本文探讨了单例模式在序列化和反序列化过程中的问题,即反序列化后得到的对象与原单例对象不相等。文章通过示例代码展示了这一现象,并介绍了如何通过在单例类中实现Serializable接口并添加readResolve方法来解决此问题。

724

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



