为什么基类(不实现Serializable)应该没有参数构造函数,如果它的子类实现Serializable?

时间:2014-07-07 16:58:24

标签: java serialization

我正在阅读界面Serializable的文档,其中我找到以下几行:

  

为了允许序列化非可序列化类的子类型,子类型可以承担保存和恢复超类型的公共,受保护和(如果可访问)包字段的状态的责任。只有当它扩展的类具有可访问的no-arg构造函数来初始化类的状态时,子类型才可以承担此责任。如果不是这种情况,则声明类Serializable是错误的。将在运行时检测到错误。

但是基类的no-arg构造函数在恢复对象状态方面的作用是什么?

2 个答案:

答案 0 :(得分:14)

当您尝试反序列化可序列化对象时,该机制必须创建该对象的空实例,并填写成员,以将对象还原到序列化时的状态。首次构造对象时,将调用可序列化对象的构造函数,但在反序列化期间不会调用构造函数,因为从技术上讲,您不构造对象,而是将其重构为前一个状态。预计任何构造和子序列操作的影响都已纳入对象状态。

每当构造任何类的对象时,Java必须调用超类的构造函数和超级超类等。您可以使用super(...)或者为{$ 1}}指定超类的特定构造函数。如果您没有指定超级构造函数,则将使用默认构造函数。无论如何,都构建了根的所有类。

可重新列化对象的反序列化不会导致构造函数调用,但是当存在不可序列化的超类时(即扩展具有可序列化类的非可序列化类),那么该类不希望被反序列化,它没有存储/恢复其成员的机制。如果超类不可序列化,则反序列化机制需要调用零参数构造函数以确保重构的对象实例已正确初始化。

如果未能指定零参数构造函数,则在第一次尝试反序列化该类的对象之前,反序列化代码不会警告您此问题。编译时没有警告。

此外,您的可序列化子类必须负责存储/恢复来自非序列化超类的任何成员值。

答案 1 :(得分:0)

如果超类不是Serializable而不是序列化子类的对象,我们必须明确地在子类中实现可序列化的接口。在这种情况下,超类必须包含无参数构造函数。

如果超类不是Serializable,则在反序列化过程中通过调用Non-Serializable Super class的构造函数来初始化从超类继承的实例变量的所有值。