2014-07-07 44 views
7

我读接口Serializable的文档,其中我发现下面几行:为什么基类(不实现Serializable)如果其子类实现Serializable,应该没有参数构造函数?

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

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

+0

见http://www.jguru.com/faq/view.jsp?EID=251942 – GKislin

回答

13

当您试图反序列化一个序列化对象,该机制必须创建对象的空实例,并填写会员,对象恢复到它是序列化时的状态。一个可序列化对象的构造函数在对象初次构造时会被调用,但是在反序列化过程中不会调用构造函数,因为在技术上,您不是在构造该对象,而是将其重构为前一个状态。预计任何结构和子序列操作的影响已经被纳入对象状态。

无论何时构建任何类的对象,Java必须调用超类的构造函数以及超超类等。您可以使用super(...)指定超类的特定构造函数,或者如果不不指定超级构造函数,将使用默认的构造函数。无论如何,所有到根的类都被构建。

serlializable对象的反序列化不会导致构造函数调用,但是当有一个超类,它是不可序列化(也就是你扩展不可序列化的类与序列化类),那么这个类是没有预料到被反序列化,并且它没有存储/恢复其成员的机制。如果超类不是可序列化的,则反序列化机制需要调用零参数构造函数以确保重构的对象实例已正确初始化。

如果你没有指定一个零参数的构造函数,反序列化的代码不会提醒你这个问题,直到你的第一次尝试反序列化类的一个对象。编译时没有警告。

此外,您的序列化的子类必须对存储/从非序列化父类恢复任何成员的值责任。

+0

做基类的构造函数总是系列化运行? – YakRangi

+0

如果超类是可序列化的,那么不需要arg构造函数,因为派生类对象会自动保存基类部分,因为该部分是可序列化的。] – YakRangi

+0

假设如果我们有一个arg构造函数,在不可序列化的基类中没有arg构造函数,它们是否都被调用? – YakRangi

0

如果超类是不可序列比对序列化,子类的对象,就必须在子类中显式实现Serializable接口。在这种情况下,超类必须有一个无参数的构造函数。

如果超类是不可序列然后从超类继承的实例变量的所有值都将在反序列化过程中调用非序列超类的构造函数初始化。

相关问题