Java – 反序列化InvalidClassException(无有效的构造函数)

我正在尝试序列化一个对象,然后在将其数据发送到客户端程序后反序列化它。

这是对象inheritance如何工作的一个例子。 我正在序列化和反序列化的对象是人。

生活 – >动物 – > NPC – >人 – >儿童

Living,Animal和NPC不实现Serializable。 我无法改变这三个class级。 Person和Child确实实现了Serializable。 人与生活也是抽象的阶级。 我可以将一个Person(谁是一个Child)序列化并发送它,但是当我尝试反序列化一个Person(谁是一个Child)时,我在Child上得到一个InvalidClassException,说“没有有效的构造函数”。

为什么会这样? Must Living,Animal和NPC都实现Serializable?

在以下问题的答案中做了很好的解释反序列化ArrayList。 没有有效的构造函数

长话短说 – 在你的情况下,你需要no-arg构造函数用于你的类的第一个非可序列化的超类, NPC

如果您没有NPC访问权限并且它不包含no-arg构造函数 – 那么您可以在层次结构中添加一个“假”类,它将选择正确的类。 例如

 class SomeClass extends NPC { // will be called during deserialization public SomeClass(){ // call custom constructor of NPC super(null); } } class Person extends SomeClass implements Serializable { // .. } 

根据这个线程 ,他们不需要实现Serializable,但是他们(或者至少是NPC,因为它是层次结构中的第一个非可序列化的类)必须包含0参数构造函数。 如果类中没有定义构造函数,则隐式构造函数是不合适的,但如果在这些类中定义了其他构造函数,则必须编写显式的0参数构造函数。

由于您无法控制NPC,请尝试创建它的子类,它定义了一个显式的0-param构造函数,但是它没有实现Serializable,并查看是否不这样做。

我在Hazelcast的序列化方面遇到了同样的问题,但是通过使用自定义序列化解决了它,而没有求助于中间类。 我在Animal类中添加了一个空的无参数构造函数,并按如下方式实现了Person类:

 class Person extends Animal implements Serializable { private void writeObject(ObjectOutputStream o) throws IOException { o.writeObject(this.fieldA); o.writeObject(this.fieldB); o.writeObject(this.fieldC); ... } private void readObject(ObjectInputStream o) throws IOException, ClassNotFoundException { this.fieldA = (TypeOfA) o.readObject(); this.fieldB = (TypeOfB) o.readObject(); this.fieldC = (TypeOfC) o.readObject(); ... } }