Java - 反序列化 InvalidClassException(没有有效的构造函数)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12125076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java - Deserialization InvalidClassException (No valid constructor)
提问by WildBamaBoy
I'm trying to serialize an object and then deserialize it after sending its data to a client program.
我试图序列化一个对象,然后在将其数据发送到客户端程序后反序列化它。
Here's an example of how the object's inheritance works. The object I'm serializing and deserializing is person.
这是对象的继承如何工作的示例。我正在序列化和反序列化的对象是人。
Living -> Animal -> NPC -> Person -> Child
生活 -> 动物 -> NPC -> 人 -> 孩子
Living, Animal, and NPC do not implement Serializable. I can not change those three classes. Person and Child do implement Serializable. Person and Living are also abstract classes. I can serialize a Person (who is a Child) just fine and send it, but when I attempt to deserialize a Person (who is a Child), I get an InvalidClassException on Child, saying "no valid constructor".
Living、Animal 和 NPC 不实现可序列化。我不能改变这三个类。Person 和 Child 确实实现了 Serializable。Person 和 Living 也是抽象类。我可以很好地序列化一个人(他是一个孩子)并发送它,但是当我尝试反序列化一个人(他是一个孩子)时,我在 Child 上得到一个 InvalidClassException,说“没有有效的构造函数”。
Why is this happening? Must Living, Animal, and NPC all implement Serializable?
为什么会这样?Living、Animal 和 NPC 都必须实现 Serializable 吗?
采纳答案by udalmik
Good explanation is done in answers for following question Deserializing an ArrayList. no valid constructor
在以下问题反序列化一个 ArrayList 的答案中做了很好的解释 。没有有效的构造函数
Long story short - you need no-arg constructor for first nonserializable super class of your class, NPC
in your case.
长话短说 -NPC
在您的情况下,您的类的第一个不可序列化的超类需要无参数构造函数。
If you don't have an access to NPC and it doesn't contain no-arg constructor - then you can add one more 'fake' class to hierarchy which will choose the correct one. E.g.
如果您无法访问 NPC 并且它不包含无参数构造函数 - 那么您可以在层次结构中再添加一个“假”类,它将选择正确的类。例如
class SomeClass extends NPC {
// will be called during deserialization
public SomeClass(){
// call custom constructor of NPC
super(null);
}
}
class Person extends SomeClass implements Serializable {
// ..
}
回答by Frank Thomas
per this thread, they do not need to implement Serializable, but they (or at a minimum NPC because its the first non-serializable class in the heirarchy) must contain a 0-parameter constructor. if no constructors are defined in the classes, the implicit constructor is adaquate, but if you have other constructors defined in those classes, you must write an explicit 0-parameter constructor.
每个线程,它们不需要实现可序列化,但它们(或至少 NPC 因为它是层次结构中的第一个不可序列化的类)必须包含一个 0 参数构造函数。如果类中未定义构造函数,则隐式构造函数是适当的,但如果在这些类中定义了其他构造函数,则必须编写显式 0 参数构造函数。
Since you cannot control NPC, try creating child of it that defines an explicit 0-param constructor but that does not implement Serializable, and see if that doesn't do it.
由于您无法控制 NPC,请尝试创建它的子项,该子项定义了一个显式的 0 参数构造函数但未实现 Serializable,然后查看是否这样做。
回答by izilotti
I faced the same issue with Hazelcast's serialization, but solved it without resorting to an intermediary class, by using custom serialization. I added an empty no-arg constructor to the Animal class and implemented the Person class as follows:
我在Hazelcast的序列化中遇到了同样的问题,但通过使用自定义序列化解决了它,而无需求助于中间类。我向 Animal 类添加了一个空的 no-arg 构造函数,并按如下方式实现了 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();
...
}
}