概述:
1. 序列化的:将对象编码称为“字节流”
2. 反序列化:将“字节流”变成对象
3. 对象被序列化后:编码可以从一台虚拟机传递到另一台虚拟机,或者被存储在磁盘上[供以后反序列化的时候用][编码可以从一台虚拟机传递到另一台虚拟机?什么鬼?]
4. 序列化: 1. 为远程通信提供了标准的线路级对象表示方法 2. 为JavaBean组件提供了标准的持久化数据格式 [什么鬼?]
5. 本章需要注意的特性:序列化代理模式[帮助避免对象序列化的许多缺陷][什么鬼?]
第74条:谨慎实现Serializable接口
1. 使类的实例可以被序列化,其实是复杂的,需要谨慎使用。为序列化付出的长期开销是实在的
2. 实现Serializable接口的代价:
2.1 最大代价:一旦被发布,想改变的灵活性大大的降低。 1. 使用默认序列化形式,类后来被修改了,就会有新旧版本,存在的兼容问题会导致程序失败。 实现Serializable接口的类,其“序列化形式”[字节流编码]就变成了它API的一部分 2. 需要努力设计一种:自定义的序列化形式。并且后期长时间愿意使用这种形式。 小结:好的序列化形式,会限制类的演变;不好的序列化形式[比如:java默认序列化形式],会使得类根本无法演变
序列化会使类的演变受到限制,这种闲置的一个例子与“流的唯一标识符UID”相关[被叫做:序列版本UID]。每一个可序列化的类,都有一个UID。
如果不指定:private static final long serialVersionUID的话,系统会自动通过复杂的计算生成一个[类似于hashCode,会用到这个类的所有信息,变量,方法,实现的接口]。任何对类的修改都会导致所计算的serialVersionUID变化,从而导致:新旧版本类的兼容问题
2.2 代价2:增加了出现bug,安全漏洞的可能性。序列化是一种非常规的对象的创建机制。
2.3 代价3:随着新版本的发布,相关的测试负担也增加了。需要确保“序列化-反序列化”成功,也要保证“产生的是原来对象的复制品”。根据经验:Date,BigInteger,大多数集合类应该实现Serializable
为了继承而设计的类,应该尽可能少的去实现Serializable。否则,扩展时候负担沉重。
但是,某些情况下,确实需要实现Serializable,比如:为框架设计的类,接口
j2se中:Throwable,HttpServlet实现了Serializable,用于将RMI的异常从服务器传到客户端,session的持久化
第75条:考虑使用自定义的序列化形式
1. 时间紧迫的情况下,工作的重心是:设计最佳的API。具体的实现:可能是用完后就丢弃,以后的新版本会重新实现
2.