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

时间:2012-08-25 19:40:02

标签: java serialization deserialization

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

以下是对象继承如何工作的示例。我正在序列化和反序列化的对象是人。

生活 - >动物 - > NPC - >人 - >子

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

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

3 个答案:

答案 0 :(得分:13)

在以下问题的答案中做了很好的解释 Deserializing an ArrayList. no valid constructor

长话短说 - 对于你的类中的第一个非可序列化超类,你需要no-arg构造函数,NPC

如果您无法访问NPC并且它不包含no-arg构造函数 - 那么您可以在层次结构中添加一个“假”类,这将选择正确的类。 E.g。

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

class Person extends SomeClass implements Serializable {
// ..
}

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

我遇到了与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();
        ...
    }
}