【问题标题】:Serializable and Externalizable. Difference of constructor invocation while deserialization可序列化和可外部化。反序列化时构造函数调用的区别
【发布时间】:2015-02-21 08:56:31
【问题描述】:

我已阅读以下文章:

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

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

构造函数调用是真的吗

可序列化:
而反序列化只调用最近的非Serializable祖先的构造函数

可外部化:
而反序列化只调用实现Externalizable接口的类的构造函数。

?

【问题讨论】:

  • 忽略任意互联网垃圾,直接进入对象序列化规范,它与您的断言一致。

标签: java serialization externalizable


【解决方案1】:

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

许多反序列化器只使用 Unsafe.allocateInstance() 并且不调用任何构造函数。这样做是为了最大限度地减少反序列化时的副作用。

【讨论】:

    【解决方案2】:

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

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

    另外我想告诉你,在 Externalizable 的情况下,没有强制要求没有参数的构造函数。我们可以通过在构造函数初始化期间将所有参数传递为 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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-29
      • 2015-10-12
      • 2011-11-05
      • 2014-03-19
      • 1970-01-01
      相关资源
      最近更新 更多