单例设计模式-序列化破坏单例模式?

1、问题猜想,假如将一个对象通过序列化放到一个文件后,再取出来看是否与本身相等?
public class HungrySingleton implements Serializable {

  private final static HungrySingleton hungrySingleton;

  static {
    hungrySingleton = new HungrySingleton();
  }

  private HungrySingleton() {

  }
  public static HungrySingleton getInstance() {
    return hungrySingleton;
  }
}

public class Test {

  public static void main(String[] args) throws IOException, ClassNotFoundException {

    HungrySingleton instance = HungrySingleton.getInstance();
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("single_file"));
    oos.writeObject(instance);

    File file = new File("single_file");
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
    HungrySingleton newInstance = (HungrySingleton) ois.readObject();

    System.out.println(instance);
    System.out.println(newInstance);
    System.out.println(instance == newInstance);
  }
}

结果:

com.wenwen.design.pattern.Creational.singleton.HungrySingleton@45ee12a7
com.wenwen.design.pattern.Creational.singleton.HungrySingleton@7699a589
false

由此可见,instance和newInstance不相等,就违背了单例模式的一个初衷,通过序列化和反序列化拿到了不同的对象。而我们是希望拿到一个对象。

那么如何解决呢?

在单例中加一个方法就可解决,如下代码所示:

public class HungrySingleton implements Serializable {

  private final static HungrySingleton hungrySingleton;

  static {
    hungrySingleton = new HungrySingleton();
  }

  private HungrySingleton() {

  }
  public static HungrySingleton getInstance() {
    return hungrySingleton;
  }
  private Object readResolve() {
    return hungrySingleton;
  }
}

再次运行测试类之后,结果如下:

com.wenwen.design.pattern.Creational.singleton.HungrySingleton@45ee12a7
com.wenwen.design.pattern.Creational.singleton.HungrySingleton@45ee12a7
true

为什么如此神奇呢?这就要大家深入看下源码了。按command+enter进行该处的源码。

 

 

因为使用了序列化,则会new一个新的实例,所以前面看到会返回两个不同的实例。

 

因为代码里写了readResolve()方法,会反射出原先的实例进行返回,则写了readResolve()方法之后,会返回同一个实例。

 

 

 

 

 

 

 

 
posted @ 2019-04-16 20:28  左手背右手背  阅读(534)  评论(0编辑  收藏  举报