在Serializable类中使用私有构造函数扩展类

时间:2013-07-29 10:36:30

标签: java inheritance serialization constructor

详细介绍http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html

上的Serializable的文档

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

通常,任何具有私有构造函数的类都无法扩展。此错误将在编译时显示。但上述文档的最后一行表明它将在运行时发生。有什么解释吗?

2 个答案:

答案 0 :(得分:3)

该文档说不可序列化的超类型需要一个无参数的构造函数。它并没有说它应该是私人的。相反,它说这个构造函数应该是可访问的。文档对运行时的意义是这个

class A {
    A() {   <-- accessible only in current package
    }
}

public class B extends A implements Serializable {
    public B() {
    }
}

让我们假设A和B都在同一个包中。没有编译错误。但是如果我们尝试在另一个包中从C类反序列化B的实例,我们将得到一个运行时异常,因为ObjectInputStream将尝试调用A的无参数构造函数,但它不能从包外部访问

答案 1 :(得分:1)

你的最后一部分解释是不正确的。 如果A的无参数构造函数对C是否可见则无关紧要。它只需要对B可见。

在坚果壳中,只要A具有B可见的无参数构造函数,就可以将B声明为可序列化。

但是原作仍然是开放的:

  

为什么在所有验证运行时都会识别出此错误   编译期间可以获得哪些信息?