Effective Java之序列化 总结

第74条 谨慎地实现Serializable接口
实现Serializable接口而付出的最大代价是 一旦一个类被发布 就大大降低了 改变这个类的实现 的灵活性
实现Serializable的第二个代价是 它增加了出现Bug和安全漏洞的可能性
实现Serializable的第三个代价是 随着类发行新的版本 相关的测试负担也增加了
实现Serializable接口并不是一个很轻松就可以做出的决定
为了继承而设计的类应该尽可能少地去实现Serializable接口 用户的接口也应该尽可能少地继承Serializable接口
对于为继承而设计的不可序列化的类 你应该考虑提供一个无参构造器
内部类不应该实现Serializable
内部类的默认序列化形式是定义不清楚的

第75条 考虑使用自定义的序列化形式
如果没有先认真考虑默认的序列化形式是否合适 则不要贸然接受
如果一个对象的物理表示法等同于它的逻辑内容 可能就适合于使用默认的序列化形式
即使你确定了默认的序列化形式是合适的 通常还必须提供一个readObject方法以保证约束关系和安全性
当一个对象的物理表示法与它的逻辑数据内容有实质性的区别时 使用默认序列化形式会有以下4个缺点:
它使这个类的导出API永远地束缚在该类的内部表示法上
它会消耗过多的空间
它会消耗过多的时间
它会引起栈溢出
如果所有的实例域都是瞬时的 从技术角度而言 不调用defaultWriteObject和defaultReadObject也是允许的 但是不推荐这样做
在决定将一个域做成非transient的之前 请一定要确信它的值将是该对象逻辑状态的一部分
如果在读取整个对象状态的任何其他方法上强制任何同步 则也必须在对象序列化上强制这种同步
不管你选择了哪种序列化形式 都要为自己编写的每个可序列化的类声明一个显示的序列版本UID

第76条 保护性地编写readObject
当一个对象被反序列化的时候 对于客户端不应该拥有的对象引用 如果哪个域包含了这样的对象引用 就必须要做保护性拷贝 这是非常重要的
不要使用writeUnshared和readUnshared方法
对于对象引用域必须保持为私有的类 要保护性地拷贝这些域中的每个对象 不可变类的可变组件就属于这一类别
对于任何约束条件 如果检查失败 则抛出一个InvalidObjectException异常 这些检查动作应该跟在所有的保护性拷贝之后
如果整个对象图在被反序列化之后必须就行验证 就应该使用ObjectInputValidation接口
无论是直接方法还是间接方式 都不要调用类中任何可被覆盖的方法

第77条 对于实例控制 枚举类型优先于readResolve
如果依赖readResolve进行实例控制 带有对象引用类型的所有实例域则都必须声明为transient的
readResolve的可访问性很重要

第78条 考虑用序列化代理代替序列化实例
每当你发现自己必须在一个不能被客户端扩展的类上编写readObject或者writeObject方法的时候 就应该考虑使用序列化代理模式 要想稳健地将带有重要约束条件的对象序列化时 这种模式可能是最容易得方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值