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

     
     
     
    想要飞得更高,就该忘记地平线!
  • 相关阅读:
    settings.xml的配置
    查看Linux防火墙状态
    Linux系统安装jdk并配置环境变量
    Windows系统与虚拟机CentOS之间文件复制
    搭建公司后台服务架构(1)
    09-http.ts配置了全局的http拦截器,单独某个组件不想要这个拦截器,如何设置
    17- vue自定义指令-操作DOM的
    15-keep-alive
    14-观察者模式和发布订阅的区别/vue响应式是发布订阅模式和观察者模式
    13.每个vue文件都是一个私有作用域/css的私有性原理
  • 原文地址:https://www.cnblogs.com/shenwen/p/10719817.html
Copyright © 2011-2022 走看看