`
dandy
  • 浏览: 68500 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

诵读困难者的一神论

    博客分类:
  • java
阅读更多
出自《java puzzle》


从前有一个人,他认为世上只有一只不寻常的狗,所以他写出了如下的类,将它作为一个单件(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。给平台设计者的教训是,隐藏的构造器,例如序列化中产生的那个,会让读者对程序行为的产生错觉.
1
0
分享到:
评论

相关推荐

    Java解惑(谜题)CHM中英文双版本

    谜题83:诵读困难者的一神论 谜题84:被粗暴地中断 谜题85:惰性初始化 Java谜题9——高级谜题 谜题86:有毒的括号垃圾 谜题87:紧张的关系 谜题88:原生类型的处理 谜题89:泛型迷药 谜题90:荒谬痛苦的...

    庐山云雾教材分析报告.docx

    - **教学目的**:通过本文的学习,不仅让学生领略到庐山云雾的美景,还希望通过诵读和感悟,让学生深入理解文本,激发对祖国山河的自豪感和对大自然美景的赞美之情。 - **内容特色**:本文语言优美,想象丰富,结构...

    基于Springboot的漫画网站--论文.zip

    Java项目基于springboot的课程设计,包含源码+数据库+毕业论文

    Java毕业设计-SpringBoot+Vue的分布式架构网上商城(附源码、数据库、教程).zip

    Java 项目, Java 毕业设计,Java 课程设计,基于 SpringBoot 开发的,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行! 1. 技术组成 前端:html、javascript、Vue 后台框架:SpringBoot 开发环境:idea 数据库:MySql(建议用 5.7 版本,8.0 有时候会有坑) 数据库工具:navicat 部署环境:Tomcat(建议用 7.x 或者 8.x 版本), maven 2. 部署 如果部署有疑问的话,可以找我咨询 Java工具包下载地址: https://pan.quark.cn/s/eb24351ebac4 后台路径地址:localhost:8080/项目名称/admin/dist/index.html 前台路径地址:localhost:8080/项目名称/front/index.html (无前台不需要输入)

    GUI面板MATLAB漂浮物识别.zip

    GUI面板MATLAB漂浮物识别

    【工程项目】MATLAB道路桥梁裂缝检测[不同类型,GUI界面,Bp算法].zip

    【工程项目】MATLAB道路桥梁裂缝检测[不同类型,GUI界面,Bp算法]

    Delphi 12.3控件之高仿银豹手机APP 1.0.zip

    Delphi 12.3控件之高仿银豹手机APP 1.0.zip

    springboot高校食堂移动预约点餐系统.zip

    ava项目springboot基于springboot的课程设计,包含源码+数据库+毕业论文

    基于SSM+JSP的定西扶贫惠农推介系统+数据库(Java毕业设计,包括源码,教程).zip

    Java 项目, Java 毕业设计,Java 课程设计,基于 SpringBoot 开发的,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行! 1. 技术组成 前端:jsp 后台框架:SSM 开发环境:idea 数据库:MySql(建议用 5.7 版本,8.0 有时候会有坑) 数据库工具:navicat 部署环境:Tomcat(建议用 7.x 或者 8.x 版本), maven 2. 部署 如果部署有疑问的话,可以找我咨询 Java工具包下载地址: https://pan.quark.cn/s/eb24351ebac4

    GUI面板MATLAB指纹识别.zip

    GUI面板MATLAB指纹识别

    【工程项目】MATLAB的病虫害检测系统(SVM方法,GUI界面).zip

    【工程项目】MATLAB的病虫害检测系统(SVM方法,GUI界面)

    基于ssm+vue的药品商超管理系统(java毕业设计,包括源码,数据库,教程).zip

    Java 项目, Java 毕业设计,Java 课程设计,基于 SSM 开发的,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行! 1. 技术组成 前端:vue/html5 后台框架:SSM 开发环境:idea 数据库:MySql(建议用 5.7 版本,8.0 有时候会有坑) 数据库工具:navicat 部署环境:Tomcat(建议用 7.x 或者 8.x 版本), maven 2. 部署 如果部署有疑问的话,可以找我咨询 Java工具包下载地址: https://pan.quark.cn/s/eb24351ebac4

    Java毕业设计-SpringBoot+Vue的旅游管理系统(附源码,数据库).zip

    Java 项目, Java 毕业设计,Java 课程设计,基于 SpringBoot 开发的,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行! 1. 技术组成 前端:html、javascript、Vue 后台框架:SpringBoot 开发环境:idea 数据库:MySql(建议用 5.7 版本,8.0 有时候会有坑) 数据库工具:navicat 部署环境:Tomcat(建议用 7.x 或者 8.x 版本), maven 2. 部署 如果部署有疑问的话,可以找我咨询 Java工具包下载地址: https://pan.quark.cn/s/eb24351ebac4 后台路径地址:localhost:8080/项目名称/admin/dist/index.html 前台路径地址:localhost:8080/项目名称/front/index.html (无前台不需要输入)

    Java毕业设计-SpringBoot+Vue的基于SpringBoot的CSGO赛事管理系统(附源码、数据库、教程).zip

    Java 项目, Java 毕业设计,Java 课程设计,基于 SpringBoot 开发的,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行! 1. 技术组成 前端:html、javascript、Vue 后台框架:SpringBoot 开发环境:idea 数据库:MySql(建议用 5.7 版本,8.0 有时候会有坑) 数据库工具:navicat 部署环境:Tomcat(建议用 7.x 或者 8.x 版本), maven 2. 部署 如果部署有疑问的话,可以找我咨询 Java工具包下载地址: https://pan.quark.cn/s/eb24351ebac4 后台路径地址:localhost:8080/项目名称/admin/dist/index.html 前台路径地址:localhost:8080/项目名称/front/index.html (无前台不需要输入)

    2023年计算机组成与维护教程题库及答案.pdf

    2023年计算机组成与维护教程题库及答案.pdf

    本文章是本人在学习初阶数据结构的随手笔记,不具有任何教学功能,仅供参考

    本文章是本人在学习初阶数据结构的随手笔记,不具有任何教学功能,仅供参考

    #深度学习环境配置#CUDA+CUDNN+pycharm

    #深度学习环境配置#CUDA+CUDNN+pycharm

    springboot-时间管理系统 LW PPT.zip

    ava项目springboot基于springboot的课程设计,包含源码+数据库+毕业论文

    2023年全国计算机二级笔记.pdf

    2023年全国计算机二级笔记.pdf

    【工程项目】MATLAB的CNN卷积神经网络疲劳检测(卷积神经网络).zip

    【工程项目】MATLAB的CNN卷积神经网络疲劳检测(卷积神经网络)

Global site tag (gtag.js) - Google Analytics