Effective Java 76 Write readObject methods defensively
Principle
- 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.
- When an object is deserialized, it is critical to defensively copy any field containing an object reference that a client must not possess.
- Do not use the writeUnshared and readUnshared methods.
- 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
- 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.
- Check any invariants and throw an InvalidObjectException if a check fails. The checks should follow any defensive copying.
- If an entire object graph must be validated after it is deserialized, use the ObjectInputValidation interface [JavaSE6, Serialization].
- 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的更多相关文章
- Effective Java 54 Use native methods judiciously
Java Native Interface(JNI) allows Java applications to call native methods, which are special method ...
- Effective Java 27 Favor generic methods
Static utility methods are particularly good candidates for generification. The type parameter list, ...
- 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 ...
- 《Effective Java》读书笔记 - 11.序列化
Chapter 11 Serialization Item 74: Implement Serializable judiciously 让一个类的实例可以被序列化不仅仅是在类的声明中加上" ...
- Effective Java 目录
<Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...
- Effective Java 第三版——17. 最小化可变性
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 【Effective Java】阅读
Java写了很多年,很惭愧,直到最近才读了这本经典之作<Effective Java>,按自己的理解总结下,有些可能还不够深刻 一.Creating and Destroying Obje ...
- Effective Java 75 Consider using a custom serialized form
Principle Do not accept the default serialized form without first considering whether it is appropri ...
- EFFECTIVE JAVA 第十一章 系列化
EFFECTIVE JAVA 第十一章 系列化(将一个对象编码成一个字节流) 74.谨慎地实现Serializable接口 *实现Serializable接口付出的代价就是大大降低了“改变这个类 ...
随机推荐
- SQL Server里的INTERSECT ALL
在上一篇文章里,我讨论了INTERSECT设置操作的基础,它和INNER JOIN的区别,还有为什么需要好的索引设计支持.今天我想谈下SQL Server里并未实现的INTERSECT ALL操作. ...
- An Introduction to Garbage Collection(垃圾回收简介)
1. Introduction 2. Principles 3. Advantages 4. Disadvantages 5. 常见的垃圾回收技术 5.1. 跟踪式垃圾回收 5.1.1. 基本算法 5 ...
- Velocity魔法堂系列一:入门示例
一.前言 Velocity作为历史悠久的模板引擎不单单可以替代JSP作为Java Web的服务端网页模板引擎,而且可以作为普通文本的模板引擎来增强服务端程序文本处理能力.而且Velocity被移植到不 ...
- JAVA魔法堂:折腾Mybatis操作SQLite的SQLException:NYI异常
一.坑爹 在使用Mybatis3.2.7+sqlite-jdbc3.3时,在执行查询操作,不管returnType和parameterType传什么值均报位于mapper.xml文件中的java.sq ...
- 通过刷bios的方式在win8.1平板上启动windows phone模拟器
最近买了个Windows8.1平板电脑,不是Surface Pro,太贵,而是国产的乐凡F2(64G.4G内存),CPU是赛扬U1037.最开始安装Visual Studio2013以及其他开发工具都 ...
- Sprint第三个冲刺(第四天)
一.Sprint介绍 任务进度: 二.Sprint周期 看板: 燃尽图:
- [课程设计]Scrum日记本项目进度
Sprint 1时间:11.14-11.23 冲刺一这一阶段中主要实现的是界面和互交(已实现这两个功能) 燃尽图: 项目进度: 第一阶段:现阶段已经实现界面和互交. 第二阶段:进行填入信息,并记录日期 ...
- 在Hdsi2.0 SQL的注入部分抓包分析语句
在Hdsi2.0 SQL的注入部分抓包分析语句 恢复cmd ;insert tb1 exec master..xp_cmdshell''net user ''-- ;exec master.dbo.s ...
- ahjesus C# 4.0 Parallel 并行运算
Parallel.For - for 循环的并行运算 Parallel.ForEach - foreach 循环的并行运算 Parallel.Invoke - 并行调用多个任务 Task - 任务,基 ...
- centos下完全卸载mysql
版权声明:本文为博主原创文章,未经博主允许不得转载. yum方式安装的MySQL 1.yum remove mysql mysql-server mysql-libs compat-mysql51 2 ...