Effective Java (第十一章-序列化)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BlueSky003/article/details/81012466

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

1、序列化,将一个对象编码成一个字节流。相反的过程称为反序列化。

代价
1、一旦一个类被发布,就大大降低了 “改变这个类的实现” 的灵活性。
2、增加了出现 Bug 和安全漏洞的可能性。如:反序列化确保有默认的构造器。
3、随着类发行新的版本,相关的测试负担也增加。如:确保 “序列化-反序列化” 过程成功。

注意
1、为继承而设计的类应尽可能少去实现 Serializable 接口。
2、内部类不应该实现 Serializable 接口,静态内部类可以实现 Serializable 接口。

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

使用默认序列化缺点:如 外部类、内部类都要序列化。
1、它使这个类的导出 API 永远地束缚在该类的内部表示法上。
2、它会消耗过多的空间。序列化形式既表示了链表中的每个项,也表示所有的链接关系。
3、它会消耗过多的时间。
4、它会引起栈溢出。

合理的序列化
1、外部类实现 Serializable 接口。
2、外部类包含 writeObject 和 readObject 方法。
3、transient 修饰符表面该实例域将从一个类的默认序列化形式中省略掉。
4、为每个可序列化类声明一个显式的序列版本 UID。

第 76 条:保护性地编写 readObject 方法

1、对于对象引用域必须保持为私有类,要保护性地拷贝这些域中的每个对象。不可变类的可变组件就属于这一类别。
2、对于任何约束条件,如果检查失败,则抛出一个 InvalidObjectException 异常。这些检查动作应在所有的保护性拷贝之后。
3、如果整个对象图在反序列化之后必须进行验证,就应该使用 ObjectInputValidation 接口。
4、无论是直接还是间接方式,都不要调用类中任何可被覆盖的方法。

第 77 条:对于实例控制,枚举类型优先于 readResolve

1、应该尽可能地使用枚举类型来实施实例控制的约束条件。如果做不到,同时有需要一个既可实例化又是实例控制的类,就必须提供一个 readResolver 方法,并确保所有的实例域都为基本类型,或者是 transient 的。

扫描二维码关注公众号,回复: 5063306 查看本文章

第 78 条:考虑用序列化代理序列化实例

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

猜你喜欢

转载自blog.csdn.net/BlueSky003/article/details/81012466
今日推荐