单例模式再讨论(有关序列化的单例问题)
来源:互联网 发布:房贷利率折扣变化知乎 编辑:程序博客网 时间:2024/05/16 17:35
- class Dog implements Serializable{
- public static final Dog INSTANCE = new Dog();
- private Dog(){}
- }
上面能控制只生成一个单实例吗?
如果对实现了Serializable的对象进行序列化后,再反序列化,内中会不只一个实例了,因为反序列化时会重新
生成一个对象。
既然INSTANCE为静态域,那序列化时返回的对象如果也是INSTANCE就可以解决问题了,而打开API我们发现
Serializable接口确实有这样两个特殊的方法描述:
? 将对象写入流时需要指定要使用的替代对象的可序列化类,应使用准确的签名来实现此特殊方法:
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
此 writeReplace 方法将由序列化调用,前提是如果此方法存在,而且它可以通过被序列化对象的类中定义的一
个方法访问。因此,该方法可以拥有私有 (private)、受保护的 (protected) 和包私有 (package-private) 访
问。子类对此方法的访问遵循 java 访问规则。
? 在从流中读取类的一个实例时需要指定替代的类应使用的准确签名来实现此特殊方法:
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
此 readResolve 方法遵循与 writeReplace 相同的调用规则和访问规则。
上述两个方法的只要出现,就会履盖以下两个方法(这两个方法本质的意义就是用来替换序列与反序列的对
象),虽然会执行它们,但最后得到的结果却是writeReplace、readResolve两个方法写入或读出的对象:
? private void writeObject(java.io.ObjectOutputStream out) throws IOException
? private void readObject(java.io.ObjectInputStream in)throws IOException, ClassNotFoundException;
另外,writeObject与readObject需成对实现,而writeReplace与readResolve则不需要成对出现,一般单独使
用。如果同时出现这四个方法,最后写入与读出的结果以writeReplace和readResolve方法的结果为准。
所以下要解决真真单实例问题,我们如下修正:
- class Dog implements Serializable {
- public static final Dog INSTANCE = new Dog();
- private Dog() {}
- private Object readResolve() {
- return INSTANCE;
- }
- }
- public class SerialDog {
- public static void main(String[] args) throws IOException,
- ClassNotFoundException {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- new ObjectOutputStream(bos).writeObject(Dog.INSTANCE);
- ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
- Dog dog = (Dog) new ObjectInputStream(bin).readObject();
- System.out.println(dog == Dog.INSTANCE);//true
- }
- }
一个实现了Serializable的单例类,必须有一个readResolve方法,用以返回它的唯一实例。
转载自http://zha-zi.iteye.com/blog/903332
- 单例模式再讨论(有关序列化的单例问题)
- 单例模式再讨论(有关序列化的单例问题)
- 单例模式的讨论
- 单例模式的深入讨论
- java单例模式的讨论
- python的单例模式与讨论
- 单例模式的序列化
- 关于单例模式的一些讨论(实现单例模式)
- 单例的扩展性讨论
- 单例模式的问题
- 单例模式的写法和线程安全性的讨论
- 序列化 反射破坏单例模式
- 可能是最全的Java单例模式讨论
- 反射 序列化 克隆对单例模式的破坏
- 单例模式及单例对象的可序列化
- 工厂和单例模式有关了解
- 有关java中的单例模式
- 单例模式(3)- 饿汉式单例与懒汉式单例的讨论
- leetcode538 Convert BST to Greater Tree
- Tensorflow基础
- JAVA学习笔记(1)
- Python 3.6 实现简单的爬虫
- Double类型只用8字节存储但范围为什么那么大
- 单例模式再讨论(有关序列化的单例问题)
- bzoj1146: [CTSC2008]网络管理Network
- 299. Bulls and Cows
- (转)知乎:AssetMark,到底是做什么的?
- 机器学习算法及代码实现--神经网络
- 遗传算法学习材料
- 操作系统小练习6
- 句子的逆序练习题
- caffe下数据可视化