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. sql server 随机读取数据

    --sql server 随机读取数据 * FROM [tablename] ORDER BY NEWID() pk from [tablename] ORDER BY NEWID()) --这两个方 ...

  2. sysbench测试服务器性能

    sysbench目前已经有0.5的版本,不过最普遍使用的依旧是0.4.12,所以接下来我们会以0.4.12这个版本作为测试 Step1:下载安装sysbench wget http://pkgs.fe ...

  3. 高级四则运算器—结对项目反思(193 & 105)

    高级四则运算器—结对项目反思(193 & 105) 本周我和一位韩国同学(71061105)一起结对编程完成了我们的结对项目——高级的小学四则运算题目生成器. PSP表格   PSP2.1 P ...

  4. Gradle学习系列之八——构建多个Project

    在本系列的上篇文章中,我们讲到了Gradle的依赖管理,在本篇文章中,我们将讲到如何构建多个Project. 请通过以下方式下载本系列文章的Github示例代码: git clone https:// ...

  5. 循序渐进开发WinForm项目(3)--Winform界面层的项目设计

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  6. Unity3D-terrain brush地形画刷无法出现在Scene中,无法刷地图2

    原因大概是 画刷brush 太小了,地图也太小了,没出出现. 如图,非正常状态: 解决方法: tag: terrain brush not working unity

  7. WPF关闭应用程序方法

    很多人认为关闭应用程序应该很简单,例如WindowsForm里一个Application.Exit();方法就可以解决问题,但在WPF里面可别滥用,因为WPF里Application类没有该方法,倒是 ...

  8. 【百度SEO优化】如何让蜘蛛爬行你的网站

    大家都知道,现在做网站简单,但是推广就比较困难了,可能一些商家引入投资,直接烧钱做广告来推广,但是对于一些小站长,是没有那么多资金的.因此我们就要懂得一些SEO优化的知识了,简单介绍一下: 怎么让百度 ...

  9. SqlServer知识点记录分享

    知识点介绍 双向检索:这里就不大话概念了,直接说它的作用 ISNULL()函数:判断函数是否有值,如果变量没有赋值就给定指定的值,下面的例子就是如果@TOTALCOUNT变量为NULL那么就赋值为空字 ...

  10. 互联网产品团队中Web前端工程师的重要性

    国内外各大互联网公司,都有UEx/d|UCD|CDC(Customer Research & User Experience Design Center)团队. 在很多公司会认为,合格的产品经 ...