zoukankan      html  css  js  c++  java
  • 谜题83:诵读困难者的一神

    从前有一个人,他认为世上只有一只不寻常的狗,所以他写出了如下的类,将它
    作为一个单件(singleton)[Gamma95]:

    public class Dog extends Exception {
    public static final Dog INSTANCE = new Dog();
    private Dog() {}
    public String toString(){
    return "Woof";
    }
    }
    

      


    结果证明这个人的做法是错误的。你能够在这个类的外部不使用反射来创建出第
    2 个 Dog 实例吗?
    这个类可能看起来像一个单件,但它并不是。问题在于,Dog 扩展了 Exception,
    而 Exception 实现了 java.io.Serializable。这就意味着 Dog 是可序列化的

    (serializable),并且解序列(deserialization)会创建一个隐藏的构造器。
    正如下面的这段程序所演示的,如果你序列化了 Dog.INSTANCE,然后对得到的
    字节序列(byte sequence)进行解序列,最后你就会得到另外一个 Dog。该程
    序打印的是 false,表示新的 Dog 实例和原来的那个实例是不同的,并且它还打
    印了 Woof,说明新的 Dog 实例也具有相应的功能:

    import java.io.*;
    public class CopyDog{ // Not to be confused with copycat
    public static void main(String[] args){
    Dog newDog = (Dog) deepCopy(Dog.INSTANCE);
    System.out.println(newDog == Dog.INSTANCE);
    System.out.println(newDog);
    }
    // This method is very slow and generally a bad idea!
    static public Object deepCopy(Object obj){
    try{
    ByteArrayOutputStream bos =
    new ByteArrayOutputStream();
    new ObjectOutputStream(bos).writeObject(obj);
    ByteArrayInputStream bin =
    new ByteArrayInputStream(bos.toByteArray());
    return new ObjectInputStream(bin).readObject();
    } catch(Exception e) {
    throw new IllegalArgumentException(e);
    }
    }
    }
    

      


    要订正这个问题,可在 Dog 中添加一个 readResolve 方法,它可以将那个隐藏的
    构造器转变为一个隐藏的静态工厂(static factory),以返回原来那个的 Dog
    [EJ Items 2,57]。在 Dog 中添加了这个方法之后,CopyDog 将打印 true 而不是
    false,表示那个“复本”实际上就是原来的那个实例:

    private Object readResolve(){
    // Accept no substitues!
    return INSTANCE;
    }
    

      


    这个谜题的主要教训就是一个实现了 Serializable 的单件类,必须有一个
    readResolve 方法,用以返回它的唯一的实例。一个次要的教训就是,有可能由
    于对一个实现了 Serializable 的类进行了扩展,或者由于实现了一个扩展自
    Serializable 的接口,使得我们在无意中实现了 Serializable。给平台设计者
    的教训是,隐藏的构造器,例如序列化中产生的那个,会让读者对程序行为的产
    生错觉。

  • 相关阅读:
    计算机顶级期刊和会议
    在linux下查看内核版本、gcc版本、操作系统多少位等参数
    GDB调试
    JAVA学习笔记1
    vim下中文乱码问题解决办法
    MATLAB light material lighting
    Matlab2012a第一次安装打不开 查找程序安装类时出错
    vim 安装与运行以及代码的运行
    express 命令汇总
    mongodb 简单命令汇总
  • 原文地址:https://www.cnblogs.com/yuyu666/p/9842421.html
Copyright © 2011-2022 走看看