Principle

  1. readObject method is effectively another public constructor, and it demands all of the same care as any other constructor. Just as a constructor must check its arguments for validity (Item 38) and make defensive copies of parameters where appropriate (Item 39), so must a readObject method.
  2. When an object is deserialized, it is critical to defensively copy any field containing an object reference that a client must not possess.
  3. Do not use the writeUnshared and readUnshared methods.
  4. If it is not comfortable adding a public constructor that took as parameters the values for each nontransient field in the object and stored the values in the fields with no validation, you must provide a readObject method, and it must perform all the validity checking and defensive copying that would be required of a constructor. Alternatively, you can use the serialization proxy pattern(Item 78).

/**

* @author Kaibo Hao Immutable class that uses defensive copying

*/

public final class Period implements Serializable {

private Date start;

private Date end;

/**

* @param start

* the beginning of the period

* @param end

* the end of the period; must not precede start

* @throws IllegalArgumentException

* if start is after end

* @throws NullPointerException

* if start or end is null

*/

public Period(Date start, Date end) {

this.start = new Date(start.getTime());

this.end = new Date(end.getTime());

if (this.start.compareTo(this.end) > 0)

throw new IllegalArgumentException(start + " after " + end);

}

public Date start() {

return new Date(start.getTime());

}

public Date end() {

return new Date(end.getTime());

}

public String toString() {

return start + " - " + end;

}

// Remainder omitted

// readObject method with defensive copying and validity checking

private void readObject(ObjectInputStream s) throws IOException,

ClassNotFoundException {

s.defaultReadObject();

// Defensively copy our mutable components

start = new Date(start.getTime());

end = new Date(end.getTime());

// Check that our invariants are satisfied

if (start.compareTo(end) > 0)

throw new InvalidObjectException(start + " after " + end);

}

}

Guidelines for writing a bulletproof readObject method

  1. For classes with object reference fields that must remain private, defensively copy each object in such a field. Mutable components of immutable classes fall into this category.
  2. Check any invariants and throw an InvalidObjectException if a check fails. The checks should follow any defensive copying.
  3. If an entire object graph must be validated after it is deserialized, use the ObjectInputValidation interface [JavaSE6, Serialization].
  4. Do not invoke any overridable methods in the class, directly or indirectly.

Summary

Anytime you write a readObject method, adopt the mind-set that you are writing a public constructor that must produce a valid instance regardless of what byte stream it is given. Do not assume that the byte stream represents an actual serialized instance.

Effective Java 76 Write readObject methods defensively的更多相关文章

  1. Effective Java 54 Use native methods judiciously

    Java Native Interface(JNI) allows Java applications to call native methods, which are special method ...

  2. Effective Java 27 Favor generic methods

    Static utility methods are particularly good candidates for generification. The type parameter list, ...

  3. Effective Java Index

    Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...

  4. 《Effective Java》读书笔记 - 11.序列化

    Chapter 11 Serialization Item 74: Implement Serializable judiciously 让一个类的实例可以被序列化不仅仅是在类的声明中加上" ...

  5. Effective Java 目录

    <Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...

  6. Effective Java 第三版——17. 最小化可变性

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. 【Effective Java】阅读

    Java写了很多年,很惭愧,直到最近才读了这本经典之作<Effective Java>,按自己的理解总结下,有些可能还不够深刻 一.Creating and Destroying Obje ...

  8. Effective Java 75 Consider using a custom serialized form

    Principle Do not accept the default serialized form without first considering whether it is appropri ...

  9. EFFECTIVE JAVA 第十一章 系列化

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

随机推荐

  1. 探秘重编译(Recompilations)(1/2)

    这篇文章我想谈下SQL Server里一个非常重要的性能调优话题:重编译(Recompilations) .当你执行非常简单的存储过程(使用临时表)时,就会发生.今天我想奠定SQL Server里重编 ...

  2. SQL Server里等待统计(Wait Statistics)介绍

    在今天的文章里我想详细谈下SQL Server里的统计等待(Wait Statistics),还有她们如何帮助你立即为什么你的SQL Server当前很慢.一提到性能调优,对我来说统计等待是SQL S ...

  3. C#语法糖之 cache操作类 asp.net

    因为考虑到我下面我将写session cookies 等 操作类 ,与cache具有共性. 所以都统一继承了IHttpStorageObject  abstract class 来保函数风格的统一 , ...

  4. Scrum团队成立

    1.团队名称:瘦子不吃肥肉 目标:学习更多,了解更多! 口号:加油 团队照: 2.角色分配: 产品负责人:卓嘉炜        http://www.cnblogs.com/luoliuxi/ Scr ...

  5. 字符串 - 近似回文词 --- csu 1328

    近似回文词 Problem's Link:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1328 analyse: 直接暴力枚举每一个终点,然后枚举 ...

  6. Google的分布式关系型数据库F1和Spanner

    F1是Google开发的分布式关系型数据库,主要服务于Google的广告系统.Google的广告系统以前使用MySQL,广告系统的用户经常需要使用复杂的query和join操作,这就需要设计shard ...

  7. 【转】MSMQ 微软消息队列 简单 示例

    MSMQ它的实现原理是:消息的发送者把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中:本地或者是异地的消息接收程 ...

  8. 线段树区间求最大值(点更新)---I Hate It

    HDU   1754 Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的 ...

  9. PowerBuilder反编译

            最近需要了解某个PowerBuilder程序如何工作的,这已经是某个时代的产物了.除了EXE之外,还有一些PBD文件.PBD文件是PowerBuilder动态库,作为本地DLL的一个替 ...

  10. html alert 的三种方式

    html alert 一共有三种方式. 第一种是最简单的直接在js的函数里alert("要输出的内容"); 这种直接就是一个弹出框,显示要输出的内容. 第二种是带选择的弹出框,弹出 ...