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. Windows Azure Web Site (17) 设置Web App TimeOut时间

    <Windows Azure Platform 系列文章目录> 我们在开发Azure Web App的时候,如果页面加载时间过长,可能需要设置Time Out时间. 在这里笔者简单介绍一下 ...

  2. 快速暴力解决Eclipse ADT和Android Studio兼容问题,创建同时兼容ADT和AS的安卓工程

    环境:AS 2.1.2+Java1.7+Gradle 2.14+ADT 24.0.2+MyEclipse 2015 前言:因为比赛要求使用ADT,而我本身比较习惯使用AS开发,遂想办法打造兼容两个ID ...

  3. Node.js基于Express框架搭建一个简单的注册登录Web功能

    这个小应用使用到了node.js  bootstrap  express  以及数据库的操作 :使用mongoose对象模型来操作 mongodb 如果没了解过的可以先去基本了解一下相关概念~ 首先注 ...

  4. 双系统Ubuntu无法访问windows磁盘分区解决方法

    为了更好的体验各种操作系统,在电脑中安装双系统是很好的选择,但在使用中难免会遇到这样或那样的问题. 最近总是遇到Ubuntu系统下无法访问windows磁盘分区问题,看了系统日志发现是挂载磁盘出问题了 ...

  5. csharp: Export or Import excel using NPOI

    excel 2003: using System; using System.Collections.Generic; using System.ComponentModel; using Syste ...

  6. KMP的原理详细讲解

    1.kmp算法的原理: 本部分内容转自:http://www.cnblogs.com/c-cloud/p/3224788.html及                           http:// ...

  7. css中important的用处

    今天看代码时遇到一段不理解的地方. #note_content { line-height: 22px; border: #DEDEDE 1px solid; background: #FAFAFA; ...

  8. php学习笔记:利用gd库生成图片,并实现随机验证码

    说明:一些基本的代码我都进行了注释,这里实现的验证码位数.需要用的字符串都可以再设置.有我的注释,大家应该很容易能看得懂. 基本思路: 1.用mt_rand()随机生成数字确定需要获取的字符串,对字符 ...

  9. 硅谷新闻3--使用Android系统自带的API解析json数据

    NewsCenterPagerBean2 bean2 = new NewsCenterPagerBean2(); try { JSONObject object = new JSONObject(js ...

  10. www.97top10.com--做最好的技术交流网站

    www.97top10.com--做最好的技术交流网站