“将一个对象编码成一个字节流”,称作将该对象序列化(serializing); 相反的处理过程被称作反序列化(deserializing),一旦对象被序列化后,它的编码就可以从一台正在运行的虚拟机被传递到另一台虚拟机上,或者被存储到磁盘上,供以后反序列化时用。序列化技术为远程通信提供了标准的线路级(wire-level)对象表示法,也为JavaBeans组件结构提供了标准的持久化数据格式。

第74条:谨慎地实现Serializable接口

代价一:牺牲灵活性

实现Serializable接口而付出的最大代价是.一旦一个类被发布,就大大降低了‘’改变这个类的实现”的灵活性。如果一个类实现了Serializable接口。它的字节流编码(或者说序列化形式,serialized form)就变成了它的导出的API的一部分。一旦这个类被广泛使用,往往必须永远支持这种序列化形式,就好像你必须要支持导出的API的所有其他部分一样。

序列化会使类的演变受到限制。这种限制的一个例子与流的唯一标识符(stream unique

identifier)有关,通常它也被称为序列版本UID ( serial version UID) 。每个可序列化的类都有一个唯一标识号与它相关联。如果你没有在一个名为serialVersionUID的私有静态final的long域中显式地指定该标识号,系统就会自动地根据这个类来调用一个复杂的运算过程,从而在运行时产生该标识号。这个自动产生的值会受到类名称、它所实现的接日的名称、以及所有公有的和受保护的成员的名称所影响。如果你通过任何方式改变了这些信息,比如,增加了一个不是很重要的工具方法,自动产生的序列版本UID也会发生变化。因此,如果你没有声明一个显式的序列版本UID,兼容性将会遭到破坏,在运行时导致InvalidClassException异常。

代价二:安全漏洞

实现Serializable的第二个代价是.它增加了出现Bug和安全漏洞的可能性。通常情况下,对象是利用构造器来创建的;序列化机制是一种语言之外的对象创建机制(extralinguistic

mechanism)。无论你是接受了默认的行为,还是覆盖了默认的行为,反序列化机制,deserialization)都是一个“隐藏的构造器”,具备与其他构造器相同的特点。因为反序列化机制中没有显式的构造器,所以你很容易忘记要确保: 反序列化过程必须也要保证所有“由真正的构造器建立起来的约束关系”。并且不允许攻击者访问正在构造过程中的对象的内部信息。

值类或集合类可考虑实现Serializable

实现Serializable接口并不是一个很轻松就可以做出的决定。它提供了一些实在的益处: 如果一个类将要加人到某个框架中,并且该框架依赖于序列化来实现对象传输或者持久化,对于这个类来说,实现Serializable接口就非常有必要。根据经验,比如Date和BigInteger这样的值类应该实现Serializable,大多数的集合类也应该如此。代表活动实体的类,比如线程池( thread pool ),一般不应该实现Serializable。

为了继承而设计的类应该尽可能少地去实现Serializable接口,用户的接口也应该尽可能少地继承Serializable接口。

第75条:考虑使用自定义的序列化形式

如果没有先认真考虑默认的序列化形式是否合适,则不要贸然接受。

不管你选择了哪种序列化形式,都要为自己编写的每个可序列化的类声明一个显式的序列版本UID (serial version UID)。这样可以避免序列版本UID成为潜在的不兼容根源。

《Effective Java》第11章 序列化的更多相关文章

  1. [Effective Java]第十一章 序列化

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  2. EFFECTIVE JAVA 第十一章 系列化

    EFFECTIVE  JAVA  第十一章  系列化(将一个对象编码成一个字节流) 74.谨慎地实现Serializable接口 *实现Serializable接口付出的代价就是大大降低了“改变这个类 ...

  3. effective java 第2章-创建和销毁对象 读书笔记

    背景 去年就把这本javaer必读书--effective java中文版第二版 读完了,第一遍感觉比较肤浅,今年打算开始第二遍,顺便做一下笔记,后续会持续更新. 1.考虑用静态工厂方法替代构造器 优 ...

  4. [Effective Java]第六章 枚举和注解

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. [Effective Java]第七章 方法

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  6. [Effective Java]第三章 对所有对象都通用的方法

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. [Effective Java]第五章 泛型

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  8. [Effective Java]第四章 类和接口

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. 《Effective Java》学习笔记 —— 序列化

    Java的序列化API提供了一个框架,用来将对象编码成一个字节流(序列化,serializing),并从字节流中重新创建对象(反序列化, deserializing). 第74条 谨慎地实现Seria ...

随机推荐

  1. poj1321

    这个题要是乍一看很难会想深搜,确实如此,可如果知道了深搜的方法,这个题就简 了不少,至于用深搜的时候要考虑当k==n和k<n时这咱种情况,当K==n时,当然很好想 到深搜搜下很容易找到所有方法, ...

  2. GMchess Linux下的中国象棋游戏

    gmchess,一款Linux下的中国象棋程序

  3. 深入理解java虚拟机 精华总结(面试)(转)

    一.运行时数据区域 3 1.1 程序计数器 3 1.2 Java虚拟机栈 3 1.3 本地方法栈 3 1.4 Java堆 3 1.5 方法区 3 1.6 运行时常量池 4 二. hotspot虚拟机对 ...

  4. SQL Server获取TEXT字段的内容长度

    DATALENGTH 返回任何表达式所占用的字节数. 语法 DATALENGTH ( expression ) 参数 expression 任何类型的表达式. 返回类型 int 注释 DATALENG ...

  5. java代码异常捕获throws抛出异常

    总结:Throwable 是所以异常的父类.error和Exception是继承它的类 Exception: 这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环 ...

  6. mysql update不支持子查询更新

    先看示例: SELECT uin,account,password,create_user_uin_tree FROM sys_user 结果: 表中的create_user_uin_tree标识该条 ...

  7. OpenCV 视频监控(Video Surveilance)的算法体系

    如前面说到的,OpenCV VS提供了6组算法的接口,分别是:前景检测.新目标检测.目标跟踪.轨迹生成.跟踪后处理.轨迹分析,除了轨迹生成用于轨迹数据的保存以外,其他5个部分都是标准的视频监控算法体系 ...

  8. MFRC522模块开发笔记

    Write_to_Card(-)和Read_from_Card(-)可谓是所有函数的终点,而SPIWriteByte(-)则是最底层对MFRC522模块进行操作的函数,所有函数都是为了Write_to ...

  9. JS和OC间的通信(使用JavaScriptCore)

    JavaScriptCore 时代的通讯 iOS 7 开始,苹果提供了一个叫作 JavaScriptCore 的框架,使用 JavaScriptCore 框架可以实现 OC 和 JS 的互相调用,而不 ...

  10. 下拉列表---demo---bai

    select.jsp <%@ page language="java" import="java.util.*" pageEncoding="U ...