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. SQL Server里的自旋锁介绍

    在上一篇文章里我讨论了SQL Server里的闩锁.在文章的最后我给你简单介绍了下自旋锁(Spinlock).基于那个基础,今天我会继续讨论SQL Server中的自旋锁,还有给你展示下如何对它们进行 ...

  2. 前端翻译:Activating Browser Modes with Doctype

    一.前言 原本备份: http://www.cnblogs.com/fsjohnhuang/p/3830623.html 由于本人英语能力有限,译本内容难免有误,望各位指正! 本译文不含附录部分,请知 ...

  3. Device eth0 does not seem to be present,delaying initialization解决方法

    Bringing up interface eth0:  Device eth0 does not seem to be present, delaying initialization. 在linu ...

  4. P6 EPPM R16.1安装与配置指南(二)

    P6 EPPM R16.1安装与配置指南(一) http://www.cnblogs.com/endv/p/5634620.html P6 EPPM R16.1安装与配置指南(二) 环境变量配置 新建 ...

  5. DataTable 获取列名 DataTable批量更新至数据库

    好久没写东西了,这几个月也没下功夫钻研技术,愧疚啊.说下最近刚学会的DataTable 的用法吧,新手适合看下. 1 DataTable 获取列名 在处理数据的时候大家都会用到模型,从datatabl ...

  6. 【BZOJ 4326】【NOIP2015】运输计划

    http://www.lydsy.com/JudgeOnline/problem.php?id=4326 题目描述 公元2044年,人类进入了宇宙纪元. 国有个星球,还有条双向航道,每条航道建立在两个 ...

  7. 【Java Saves!】Session 5:计算机器之三--二指禅

    人有十指.人类掰着手指头,发明出了0.1.2-9这十个数字.后来手指头不够用了,便发明出数位(个.十.百.千-)和满十进一的规则,称为十进制. 而计算机靠两个手指头工作.在计算机内部,只有0和1两个数 ...

  8. Access restriction : The constructor BASE64Decoder() is not accessible due to restriction on required library

    1.问题描述 找不到包  sun.misc.BASE64Encoder 2. 解决方案 只需要在project build path中先移除JRE System Library,再添加库JRE Sys ...

  9. 那些教程没有的php3-命名空间

    php.net (PHP 5 >= 5.3.0, PHP 7) 定义命名空间 虽然任意合法的PHP代码都可以包含在命名空间中,但只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和tra ...

  10. C语言动态调用库(转)

    转自:http://cloverprince.iteye.com/blog/481309 现有一个主程序用C语言写成.现在要允许第三方开发人员编写扩展的模块,约定第三方开发的模块必须提供一系列已知名称 ...