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

     
     
     
    想要飞得更高,就该忘记地平线!
  • 相关阅读:
    贪心算法 Wooden Sticks
    HDOJ 2189 悼念512汶川大地震遇难同胞——来生一起走
    hdoj1069 Monkey and Banana(最长上升子序列)
    2012级计科《程序设计基础Ⅱ》期末上机考试
    Constructing Roads In JGShining's Kingdom
    c语言学习随笔之指针(二)
    c语言学习随笔之指针(一)
    遍历网页框架结构
    笔记本测试软件(让奸商头疼的软件)0
    ResizePicturevb.net
  • 原文地址:https://www.cnblogs.com/shenwen/p/10719817.html
Copyright © 2011-2022 走看看