Disadvantage of Serializable

  1. A major cost of implementing Serializable is that it decreases the flexibility to change a class's implementation once it has been released.

    If you accept the default serialized form, the class's private and package-private instance fields become part of its exported API, and the practice of minimizing access to fields (Item 13) loses its effectiveness as a tool for information hiding.

    It is possible to change the internal representation while maintaining the original serialized form (using

    ObjectOutputStream.putFields and ObjectInputStream.readFields ), but it can be difficult and leaves visible warts in the source code.

    stream unique identifiers (serial version UIDs)

    If you do not specify this number explicitly by declaring a static final long field named serialVersionUID , the system automatically generates it at runtime by applying a complex procedure to the class.

    The automatically generated value is affected by the class's name, the names of the interfaces it implements, and all of

    its public and protected members. If you fail to declare an explicit serial version UID, compatibility will be broken, resulting in an InvalidClassException at runtime.

  2. A second cost of implementing Serializable is that it increases the likelihood of bugs and security holes.

    Objects are created using constructors; serialization is an extralinguistic mechanism for creating objects. Relying on the default deserialization mechanism can easily leave objects open to invariant corruption and illegal access (Item 76).

  3. A third cost of implementing Serializable is that it increases the testing burden associated with releasing a new version of a class.

    When a serializable class is revised, it is important to check that it is possible to serialize an instance in the new release and deserialize it in old releases, and vice versa.

Principle

  1. Classes designed for inheritance (Item 17) should rarely implement Serializable, and interfaces should rarely extend it.
  2. If the class has invariants that would be violated if its instance fields were initialized to their default values (zero for integral types, false for boolean, and null for object reference types), you must add this readObjectNoData method to the class.

    // readObjectNoData for stateful extendable serializable classes

    private void readObjectNoData() throws InvalidObjectException {

    throw new InvalidObjectException("Stream data required");

    }

If a class that is designed for inheritance is not serializable, it may be impossible to write a serializable subclass. Specifically, it will be impossible if the superclass does not provide an accessible parameterless constructor.

You should consider providing a parameterless constructor on nonserializable classes designed for inheritance .

// Nonserializable stateful class allowing serializable subclass

public abstract class AbstractFoo {

private int x, y; // Our state

// This enum and field are used to track initialization

private enum State { NEW, INITIALIZING, INITIALIZED };

private final AtomicReference<State> init = new AtomicReference<State>(State.NEW);

public AbstractFoo(int x, int y) { initialize(x, y); }

// This constructor and the following method allow

// subclass's readObject method to initialize our state.

protected AbstractFoo() { }

protected final void initialize(int x, int y) {

if (!init.compareAndSet(State.NEW, State.INITIALIZING))

throw new IllegalStateException("Already initialized");

this.x = x;

this.y = y;

... // Do anything else the original constructor did

init.set(State.INITIALIZED);

}

// These methods provide access to internal state so it can

// be manually serialized by subclass's writeObject method.

protected final int getX() { checkInit(); return x; }

protected final int getY() { checkInit(); return y; }

// Must call from all public and protected instance methods

private void checkInit() {

if (init.get() != State.INITIALIZED)

throw new IllegalStateException("Uninitialized");

}

... // Remainder omitted

}

// Serializable subclass of nonserializable stateful class

public class Foo extends AbstractFoo implements Serializable {

private void readObject(ObjectInputStream s)

throws IOException, ClassNotFoundException {

s.defaultReadObject();

// Manually deserialize and initialize superclass state

int x = s.readInt();

int y = s.readInt();

initialize(x, y);

}

private void writeObject(ObjectOutputStream s)

throws IOException {

s.defaultWriteObject();

// Manually serialize superclass state

s.writeInt(getX());

s.writeInt(getY());

}

// Constructor does not use the fancy mechanism

public Foo(int x, int y) { super(x, y); }

private static final long serialVersionUID = 1856835860954L;

}

Inner classes(Item 22) should not implement Serializable. A static member class can, however, implement Serializable.

Summary

Unless a class is to be thrown away after a short period of use, implementing Serializable is a serious commitment that should be made with care. Extra caution is warranted if a class is designed for inheritance. For such classes, an intermediate design point between implementing Serializable and prohibiting it in subclasses is to provide an accessible parameterless constructor. This design point permits, but does not require, subclasses to implement Serializable.

Effective Java 74 Implement Serializable judiciously的更多相关文章

  1. Effective Java 11 Override clone judiciously

    Principles If you override the clone method in a nonfinal class, you should return an object obtaine ...

  2. Effective Java 41 Use overloading judiciously

    The choice of which overloading to invoke is made at compile time. // Broken! - What does this progr ...

  3. Effective Java 42 Use varargs judiciously

    Implementation theory The varargs facility works by first creating an array whose size is the number ...

  4. 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 ...

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

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

  6. Effective Java 目录

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

  7. 【Effective Java】阅读

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

  8. EFFECTIVE JAVA 第十一章 系列化

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

  9. Effective Java通俗理解(下)

    Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...

随机推荐

  1. Tools Function

    public static void TraceLog(string message, string logFileName) { string tmppath = AppDomain.Current ...

  2. IOS开发UI基础UILabel属性

    UILabel属性 1.text:设置标签显示的文本. 2.attributedText:设置标签属性文本. Ios代码 NSString *text = @"first";  N ...

  3. 怎么快速了解自己的MySQL服务器

      1.查看数据库服务器状态:status Linux 下的MySQL服务器状态 该列表中主要包括MySQL的版本(为version 5.1.61).运行平台(debian-linux-gnu(i68 ...

  4. GoodsAndStaffManagermentSystem----Sprint 计划1

    需求分析:茗仕茶业管理系统是个商品-员工综合管理系统. 员工管理:设置不同的职位,不同职位有不同访问权限.员工只能卖商品,财务员只有查看商品的库存量和商品销售记录:公司老板可以查看所有信息--    ...

  5. MVC+EF+esayui初试(一 布局加菜单显示)

    最近都在做linq+ext.net的开发.这两天想学习下MVC和ef,刚好,在看ext.js的时候也喜欢上了esayui,所以就想用mvc+ef+esayui做一个汽车网后台管理来加强下.在这里也把我 ...

  6. ASP.NET MVC5 网站开发实践

    http://www.cnblogs.com/mzwhj/p/3538108.html

  7. GridView如何实现双击行进行编辑,更新

    虽然标题是原创,但是其实主要的思想呢还是接见了晓风残月的思路,今天在晓风残月的博客上看到了如何利用GridView来实现双击进行编辑.我决定动手实现一下,由于还没有实现双击进行更改操作,所以顺便就把这 ...

  8. 新增的querySelector、querySelectorAll测试

    从IE9开始DOM开始支持支持CSS的选择器了,DOM提供了两个接口 querySelector 得到一个DOM querySelectorAll 得到一组DOM 一个个的解释这些选择器也没有必要,我 ...

  9. 【Unity】13.2 通过Lighting Window设置相关参数

    分类:Unity.C#.VS2015 创建日期:2016-05-19 一.简介 Unity 5.3.4的Lighting Window有3个选项卡:Object.Scene.Lightmaps. 二. ...

  10. 轻松解决MYSQL数据库连接过多的错误

    1.数据库系统允许的最大可连接数max_connections.这个参数是可以设置的.如果不设置,默认是100.最大是16384. 2.数据库当前的连接线程数threads_connected.这是动 ...