Sington类的序列化留存

Sington类的序列化

为了使Singleton类变成可序列化的(serializable),仅仅实现Serializable接口是不够的。为了维护 Singleton的单例性,你必须给Singleton类提供一个readResolve方法,否则的话,一个序列化的实例,每次反序列化的时候都会产 生一个新的实例。Singleton 也不会例外。

 

through the serializable tools, someone can write a singleton instance to disk, and then read it back up, effectively getting a new instance. Even though the constructor is private, the serializable tools have special access to create instances of a class regardless. Serialization has a special hook it uses - a private method on the class being instantiated calledreadResolve() - which is meant to supply a 'hook' for a class developer to ensure that they have a say in what object is returned by serialization. Oddly enough, readResolve() is not static, but is instead invoked on the new instance just created by the serialization. We'll get into that in a minute - for now, here is how our readResolve() method works with our singleton:

 

如下所示:

Java代码   收藏代码
  1. import java.io.FileInputStream;  
  2. import java.io.FileOutputStream;  
  3. import java.io.ObjectInputStream;  
  4. import java.io.ObjectOutputStream;  
  5. import java.io.ObjectStreamException;  
  6. import java.io.Serializable;  
  7.   
  8. //Singleton with final field  
  9. public class Singleton implements Serializable{  
  10.   
  11.     private static final long serialVersionUID = 5765648836796281035L;  
  12.     public static final Singleton uniqueInstance = new Singleton();  
  13.     private Singleton(){  
  14.     }  
  15.     //...Remainder omitted  
  16.     public static void main(String[] args) throws Exception{  
  17.         //序列化  
  18.          ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\Singleton.obj"));  
  19.          Singleton singleton = Singleton.uniqueInstance;           
  20.          objectOutputStream.writeObject(singleton);  
  21.          objectOutputStream.close();  
  22.          //反序列化  
  23.          ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\Singleton.obj"));  
  24.          Singleton singleton2 = (Singleton)objectInputStream.readObject();  
  25.          objectInputStream.close();  
  26.          //比较是否原来的实例  
  27.          System.out.println(singleton==singleton2);  
  28.    }   
  29. }  

 输出结果为:false

解决方法是为Singleton类增加readResolve()方法:

Java代码   收藏代码
  1. //readResolve 方法维持了Singleton的单例属性  
  2.     private Object readResolve() throws ObjectStreamException{  
  3.         return uniqueInstance;  
  4.     }  

 再进行测试:输出结果为true

 

反序列化之后新创建的对象会先调用此方法,该方法返回的对象引用被返回,取代了新创建的对象。本质上,该方法忽略了新建对象,仍然返回类初始化时创建的那个实例。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值