一个类实现了Serializable接口,我们就能对它的对象序列化,即把对象转换成字节数组写到内存或磁盘。反序列化时,读取内存(磁盘)中的字节数组,转换成类的对象,这个对象是一个全新的对象,和原来对象的地址是不一样的。这个过程调用了
readResolve()方法。为了避免单例的破坏,我们需要重写这个方法。
public class TestSingleton {
public static void main(String[] args) throws Exception {
/**
* 这样打印出的TestSingleton对象地址一致,
* 说明依然是单例对象
* 把readResolve方法注释掉再来一遍看看呢?
*/
System.out.println(Singleton.getInstance());
System.out.println(Singleton.getInstance().deepCopy());
}
}
//单例
class Singleton implements Serializable {
private static final long serialVersionUID = 1;
private Singleton() {
}
private static class Holder {
private static Singleton singleton = new Singleton();
}
public static Singleton getInstance() {
return Holder.singleton;
}
//重写readResolve()
private Object readResolve() throws ObjectStreamException {
return getInstance();
}
public Singleton deepCopy() throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(Singleton.getInstance());
InputStream is = new ByteArrayInputStream(os.toByteArray());
ObjectInputStream ois = new ObjectInputStream(is);
Singleton test = (Singleton) ois.readObject();
return test;
}
}