Java 编写可序列化子类
我正在阅读J.Bloch的有效Java,现在我在读关于序列化的部分。他说 如果为继承而设计的类不可序列化,则 可能无法编写可序列化的子类。具体来说,it 如果超类不提供可访问的 无参数构造函数 我不明白那个限制。我在以下课程中尝试了这一点:Java 编写可序列化子类,java,serialization,Java,Serialization,我正在阅读J.Bloch的有效Java,现在我在读关于序列化的部分。他说 如果为继承而设计的类不可序列化,则 可能无法编写可序列化的子类。具体来说,it 如果超类不提供可访问的 无参数构造函数 我不明白那个限制。我在以下课程中尝试了这一点: private static class Base { private int i; private Object o; public Base(int i, Object o){ if(i == 0 || o =
private static class Base {
private int i;
private Object o;
public Base(int i, Object o){
if(i == 0 || o == null)
throw new IllegalArgumentException("The arguments are not accepted by this constructor");
this.i = i;
this.o = o;
}
private void readObjectNoData() throws InvalidObjectException{
throw new InvalidObjectException("Stream data required");
}
}
private static class Derived extends Base implements Serializable{
public Derived(int i, Object o) {
super(i, o);
}
private static final long serialVersionUID = 1L;
}
实际上,我可以序列化派生的
的一个实例,但当我试图对其进行序列化时,我遇到了一个异常:
java.io.InvalidClassException: com.pack.age.SerializableTest$Derived; no valid constructor
你不能解释一下这些事情的意义吗?我不明白为什么在这种情况下他们需要无参数构造函数。api也需要它: 要允许序列化不可序列化类的子类型,请 子类型可能负责保存和恢复状态 超类型的公共、受保护和(如果可访问)包的 领域。只有当类 它有一个可访问的无参数构造函数来初始化 阶级的状态。如果出现以下情况,则声明类可序列化是错误的 事实并非如此。错误将在运行时检测到 在反序列化过程中,不可序列化类的字段将 使用的public或protected no arg构造函数初始化 班级。不带参数的构造函数必须可被指定的子类访问 可序列化。可序列化子类的字段将被还原 从小溪里
从文件反序列化对象时,需要能够实例化该对象。如果您有多参数
构造函数
,您将不知道如何实例化它(传递给它什么)。当Java创建派生的对象时(通过任何方式),它必须能够正确初始化基本类的状态。使用new-Derived(0,null)
时,Derived
的构造函数知道要调用Base
的哪个构造函数,以确保Base
设置正确
反序列化对象时,Java不使用构造函数;它使用单独的后门机制来设置可序列化对象的状态。不过,在这种情况下,JVM不知道如何调用超类构造函数;它唯一能做的就是调用一个无参数构造函数(这样类就可以适当地初始化它自己的私有字段)
也许Base
具有某种内部状态(保存在私有字段中),派生的无法看到。此状态未序列化(因为Base
未实现Serializable
),如果没有构造函数设置,则对象的Base
部分可能处于不一致状态。如果要反序列化对象,需要一个无参数构造函数,可以调用该构造函数
所以除了你的
public Base(int i, Object o)
添加一个无参数构造函数,如
public Base()
因为代码试图在内存中重建一个类,部分要求是它有一个无参数的公共构造函数