可序列化和可外部化。反序列化时构造函数调用的区别

时间:2014-12-23 08:24:32

标签: java serialization externalizable

我读过以下文章:

http://javapapers.com/core-java/externalizable-vs-serializable/

  

在对象反序列化(reconsturction)中公共无参数   构造函数用于重建对象。的情况下   Serializable,而不是使用构造函数,对象是   使用从ObjectInputStream读取的数据重新构建       上述要点随后要求Externalizable对象必须具有公共无参数构造函数。如果是   可以接受,这不是强制性的。

构造函数调用是否真实

序列化
反序列化仅调用最近的非Serializable祖先的构造函数

外部化
虽然反序列化调用类的构造函数,但只实现Externalizable接口。

2 个答案:

答案 0 :(得分:1)

是,在字节代码中,您可以创建对象的实例并调用层次结构中的任何构造函数。实际上,构造函数是一种特殊的方法,它甚至可以多次调用它。

许多反序列化器只使用Unsafe.allocateInstance()而不调用任何构造函数。这样做是为了最小化反序列化时的副作用。

答案 1 :(得分:1)

在Externalizable接口的情况下反序列化过程依赖于传递的构造函数,我们显式创建其对象,但在Serializable接口的情况下,对象由ObjectStreamClass.newInstance()创建。所以这里没有构造函数的作用。

之后,它在内部存储一个数据/对象数组(任何自定义字段,字符串,int ...等),它与传递的inputStream对象链接。稍后将所有数组元素(存储对象的状态)设置到对象中,它将返回到系统。

另外我想告诉大家,在Externalizable的情况下没有强制要求没有arg构造函数。我们可以通过在构造函数初始化期间将所有参数传递为null来创建对象,这样可以正常工作。

    ExternalizablePair1 copyOfPair = new ExternalizablePair1(null,null,null);

    FileInputStream inputStream = new FileInputStream(OUTPUT_FILE);
    ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
    copyOfPair.readExternal(objectInputStream);

        @Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    this.key = in.readUTF();
    this.value = in.readUTF();
    this.emp = (Employee) in.readObject();
}