Java - десериализация InvalidClassException (недействительный конструктор)
Я пытаюсь сериализовать объект, а затем десериализую его после отправки своих данных в клиентскую программу.
Вот пример того, как работает наследование объектов. Объектом, который я сериализую и десериализую, является человек.
Жизнь → Животное → NPC → Лицо → Ребенок
Жизнь, животные и NPC не реализуют Serializable. Я не могу изменить эти три класса. Человек и ребенок реализуют Serializable. Человек и жизнь - это также абстрактные классы. Я могу сериализовать Person (кто есть ребенок) просто отлично и отправить его, но когда я пытаюсь десериализовать Person (кто является дочерним), я получаю InvalidClassException для Child, говоря "no valid constructor".
Почему это происходит? Must Living, Animal и NPC все реализуют Serializable?
Ответы
Ответ 1
Хорошее объяснение сделано в ответах на следующий вопрос
Удаление десериализации 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 {
// ..
}
Ответ 2
per этот поток, им не нужно реализовывать Serializable, но они (или, как минимум, у NPC, потому что его первый несериализуемый класс в иерархии) должен содержать конструктор с 0 параметрами. если конструкторы не определены в классах, неявный конструктор является adaquate, но если у вас есть другие конструкторы, определенные в этих классах, вы должны написать явный конструктор с 0 параметрами.
Поскольку вы не можете управлять NPC, попробуйте создать дочерний элемент из него, который определяет явный конструктор 0-param, но который не реализует Serializable, и посмотрите, не делает ли это этого.
Ответ 3
Я столкнулся с той же проблемой с Hazelcast сериализацией, но решил ее, не прибегая к промежуточному классу, используя пользовательскую сериализацию. Я добавил пустой конструктор no-arg в класс 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();
...
}
}