博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Effective Java 74 Implement Serializable judiciously
阅读量:5070 次
发布时间:2019-06-12

本文共 5327 字,大约阅读时间需要 17 分钟。

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 () 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 () 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() 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.

   

   

转载于:https://www.cnblogs.com/haokaibo/p/implement-Serializable-judiciously.html

你可能感兴趣的文章
CPU,寄存器,一缓二缓.... RAM ROM 外部存储器等简介
查看>>
windows下编译FreeSwitch
查看>>
git .gitignore 文件不起作用
查看>>
Alan Turing的纪录片观后感
查看>>
c#自定义控件中的事件处理
查看>>
django Models 常用的字段和参数
查看>>
IOS--沙盒机制
查看>>
使用 JointCode.Shuttle 访问任意 AppDomain 的服务
查看>>
sqlite的坑
查看>>
digitalocean --- How To Install Apache Tomcat 8 on Ubuntu 16.04
查看>>
【题解】[P4178 Tree]
查看>>
Jquery ui widget开发
查看>>
关于indexOf的使用
查看>>
英语单词
查看>>
centos6.8下安装matlab2009(图片转帖)
查看>>
Mongo自动备份
查看>>
cer证书签名验证
查看>>
新手Python第一天(接触)
查看>>
【bzoj1029】[JSOI2007]建筑抢修
查看>>
synchronized
查看>>