16

オブジェクトをシリアル化し、そのデータをクライアント プログラムに送信した後に逆シリアル化しようとしています。

オブジェクトの継承がどのように機能するかの例を次に示します。私がシリアライズおよびデシリアライズしているオブジェクトは人です。

生活 -> 動物 -> NPC -> 人 -> 子供

Living、Animal、NPC は Serializable を実装していません。これらの 3 つのクラスを変更することはできません。Person と Child は Serializable を実装します。Person と Living も抽象クラスです。Person (子) を正常にシリアル化して送信できますが、Person (子) を逆シリアル化しようとすると、「有効なコンストラクターがありません」という子で InvalidClassException が発生します。

なぜこうなった?Living、Animal、および NPC はすべて Serializable を実装する必要がありますか?

4

3 に答える 3

13

次の質問 Deserializing an ArrayList の回答で、適切な説明が行われます。有効なコンストラクターがありません

簡単に言えば、クラスの最初のシリアル化できないスーパークラスには、引数なしのコンストラクターが必要ですNPC

NPC へのアクセス権がなく、引数のないコンストラクターが含まれていない場合は、階層に「偽の」クラスをもう 1 つ追加して、正しいクラスを選択することができます。例えば

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

class Person extends SomeClass implements Serializable {
// ..
}
于 2012-08-25T19:50:54.970 に答える
2

このスレッドによると、Serializable を実装する必要はありませんが、(階層内の最初のシリアル化不可能なクラスであるため、少なくとも NPC に) 0 パラメーターのコンストラクターを含める必要があります。クラスでコンストラクターが定義されていない場合、暗黙のコンストラクターは適切ですが、それらのクラスで他のコンストラクターが定義されている場合は、明示的な 0 パラメーターのコンストラクターを作成する必要があります。

NPC を制御できないため、明示的な 0-param コンストラクターを定義しているが Serializable を実装していないその子を作成してみて、それが行われないかどうかを確認してください。

于 2012-08-25T19:56:11.597 に答える
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();
        ...
    }
}
于 2015-06-16T18:40:30.040 に答える