1

クラス「Gambler」のコンストラクターが逆シリアル化後に呼び出される理由を誰かが説明できますが、クラス「Player」のコンストラクターは呼び出されないと言うことができますか?

import java.io.*;
  class Gambler {
   Gambler() { System.out.print("d"); }
  }
  class Person extends Gambler implements Serializable {
   Person() { System.out.print("c"); }
  }
  class Player extends Person {
   Player() { System.out.print("p"); }
 }

  class CardPlayer extends Player implements Serializable {
    CardPlayer() { System.out.print("c"); }
      public static void main(String[] args) {
      CardPlayer c1 = new CardPlayer();
      try {
            FileOutputStream fos = new FileOutputStream("play.txt");
            ObjectOutputStream os = new ObjectOutputStream(fos);
            os.writeObject(c1);
            os.close();
            FileInputStream fis = new FileInputStream("play.txt");
            ObjectInputStream is = new ObjectInputStream(fis);
            CardPlayer c2 = (CardPlayer) is.readObject();
            is.close(); 

            } 
      catch (Exception x ) { }
 }
}
4

2 に答える 2

4

クラスはインターフェースGamblerを実装していないためです。SerializableのjavadocsからSerializable

シリアル化できないクラスのサブタイプをシリアル化できるようにするために、サブタイプは、スーパータイプのパブリック、保護、および(アクセス可能な場合)パッケージフィールドの状態を保存および復元する責任を負う場合があります。サブタイプがこの責任を負うのは、サブタイプが拡張するクラスに、クラスの状態を初期化するためのアクセス可能な引数なしのコンストラクターがある場合のみです。そうでない場合、クラスSerializableを宣言するのはエラーです。エラーは実行時に検出されます。

デシリアライズ中に、シリアライズ不可能なクラスのフィールドは、クラスのpublicまたはprotectedno-argコンストラクターを使用して初期化されます。引数なしのコンストラクターは、シリアル化可能なサブクラスにアクセスできる必要があります。シリアル化可能なサブクラスのフィールドは、ストリームから復元されます。

java.io.Serializablejavaのドキュメントを参照してください。

于 2012-09-07T11:21:36.030 に答える
1

あなたの場合、serializing Object Tree is persistedオブジェクトツリーはPersonクラス次第です。Super()親クラスがどの子クラスに対してもシリアル化できない場合、メカニズムが明らかになります。これが、のコンストラクターがGambler呼び出される理由です。

詳細については、http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.htmlを参照してください。

デシリアライズ中に、シリアライズ不可能なクラスのフィールドは、クラスのpublicまたはprotectedno-argコンストラクターを使用して初期化されます。引数なしのコンストラクターは、シリアル化可能なサブクラスにアクセスできる必要があります。シリアル化可能なサブクラスのフィールドは、ストリームから復元されます。

于 2012-09-07T11:26:11.970 に答える