EffectiveJava第十一章:序列化

**对象序列化(object serialization)**API,它提供了一个框架,用来将对象编码成字节流,并从字节流编码中重新构建对象。
序列化:将对象编码成一个字节流
反序列化:将字节流编码成对象

这一章在工作很少用,不能理解很多

74. 谨慎的实现Serializable接口

实现Serializable接口可以很轻易的实现序列化,但实际上为了序列化而付出的长期开销往往是实实在在的,它的代价如下:

  1. 实现Serializable接口的最大代价是,一旦一个类被发布了,就大大降低了改变这个类的实现的灵活性。

    • 即如果接受了默认的序列化形式,这个类中私有的和包级私有的实例域将都变成导出的API的一部分。在后续发行版本中,都必须永远支持这种序列化,因为发序列形式不兼容。
      所有应该仔细的设计一种高质量的序列化形式,并且在很长时间内愿意使用这种形式。
    • 序列化会使类的演变受到限制,这种限制的一个例子与流的唯一标识符(stream unique identifier)有关,通常也被称为序列版本UID(serial version UID)。每个可序列化的类都有一个唯一标识号与它相关联。
      如果没有主动声明它,系统就会根据该类的属性和行为计算一个,当修改类的方法时该UID会变化,则会导致InvalidClassException。
  2. 第二个代价是:它增加了出现BUG和安全漏洞的可能性
    序列化机制是一种语言之外的对象创建机制。
    依靠默认的反序列机制,很容易使对象的约束关系遭到破坏,以及遭到非法访问。

  3. 第三个代价是:随着类发行新的版本,相关的测试负担也增加了。
    要检查是否可以在新版本中序列化一个实例,然后在旧版本中发序列化;反之亦然。

    • 如果一个专门为了继承而设计的类不是可序列化的,就不可能编写出可序列化的子类。
      如果超类没有提供可访问的无参构造器,子类也不可能进行序列化。所以,对于为继承而设计的不可序列化的类,应该考量提供一个无参构造器。

    • 内部类不应该实现Serializable,除了静态内部类。

总之,实现Serializable接口就是一个很严肃的承诺,必须认真对待。

75. 考虑使用自定义的序列化形式

  • 只有当你自行设计的自定义序列化形式与默认的序列化形式基本相同时,才能接受默认的序列化形式。

  • 如果一个对象的物理表示法等同于它的逻辑内容,可能就适合使用默认的序列化形式。

  • 即使你确定了默认的序列化形式使合适的,还必须提供一个readObject方法以保证约束关系和安全性。

  • 可以使用自定义的序列化形式,通过它合理的描述对象的状态。

  • 无论使用哪种序列化形式,都要主动声明一个显示的UID。

76. 保护性的编写readObject方法

readObject方法实际上相当于另一个公有的构造器。它也要求注意同样的所有注意事项。必须坚持参数有效性、必要的时候对参数进行保护性拷贝等。如果没法保证这两点,攻击者就可以很轻易的违反这个类的约束条件。
readObject是一个用字节流作为唯一参数的构造器。

77. 对于实例控制,枚举类型优先于readResolve

readResolve特性允许你用readObject创建的实例代替另一个实例。
对于一个正在被反序列的对象,如果它的类定义了一个readResolve方法,并且具备正确的声明,那么在反序列之后,新建对象上的readResolve方法就会被调用。然后该方法返回的对象引用将被返回,取代新建的对象。
如果依赖于readResolve进行实例控制,带有对象引用类型的所有实例域都必须声明为transient的。

如果将一个可序列化的实例受控的类编写成枚举,就可以绝对保证除了所声明的常量外,不会有别的实例。

78. 考虑用序列化代理代替序列化实例

每当在一个不能被客户端扩展的类上编写readObject或者writeObject方法的时候,就应该考虑使用序列化代理模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baiiu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值