zoukankan      html  css  js  c++  java
  • 单例设计模式-序列化破坏单例模式?

    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()方法之后,会返回同一个实例。

     
     
     
    想要飞得更高,就该忘记地平线!
  • 相关阅读:
    【转载】区间DP
    基础DP的一些知识总结(未完成)
    POJ2718 递归套递归
    Hadoop Illuminated——Chapter4 BigData
    Hadoop Illuminated——Chapter3 Why do I Need Hadoop?
    一条SQL语句是怎么执行的
    Github 《算法竞赛进阶指南》资源
    Hadoop——搭建Hadoop的全分布模式
    Hadoop——免密码登陆的原理和配置
    洛谷——排序P1781宇宙总统
  • 原文地址:https://www.cnblogs.com/shenwen/p/10719817.html
Copyright © 2011-2022 走看看