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

     
     
     
    想要飞得更高,就该忘记地平线!
  • 相关阅读:
    How To Scan QRCode For UWP (4)
    How To Crop Bitmap For UWP
    How To Scan QRCode For UWP (3)
    How To Scan QRCode For UWP (2)
    How To Scan QRCode For UWP (1)
    How to change windows applicatioin's position via Win32 API
    8 Ways to Become a Better Coder
    How to resize or create a thumbnail image from file stream on UWP
    C# winform压缩文件夹带进度条
    MS ACCESS MID函数
  • 原文地址:https://www.cnblogs.com/shenwen/p/10719817.html
Copyright © 2011-2022 走看看