1
import java.io.*;

public class SuperNotSerial {
public static void main(String[] args) {
    Dog d = new Dog(35, "Fido");
    System.out.println("before: " + d.name + " " + d.weight);
    try {
        FileOutputStream fs = new FileOutputStream("testSer.ser");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        os.writeObject(d);
        os.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    try {
        FileInputStream fis = new FileInputStream("testSer.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        d = (Dog) ois.readObject();
        ois.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("after: " + d.name + " " + d.weight);
}
}

class Dog extends Animal implements Serializable {
String name;

Dog(int w, String n) {
    weight = w; // inherited
    name = n; // not inherited
}
}

class Animal { // not serializable !
int weight = 42;
}

来ているエラーはです。

このエラーはコンパイル エラーであり、正確な理由を理解できません

Exception in thread "main" java.lang.NoSuchMethodError: Dog.<init>        (ILjava/lang/String;)V
at SuperNotSerial.main(SuperNotSerial.java:5)
4

1 に答える 1

1

シリアライゼーションに必要な引数のないコンストラクターが欠落しているという fge の回答に追加します。

シリアル化中に引数のないコンストラクターが必要であることを知るには、シリアル化が行われるプロセスを理解する必要があります。シリアル化は、継承階層内の各クラスを連鎖させ、最初の非シリアル化クラスに到達するまで各スーパークラスの状態を保存することによって機能します。

ここで、オブジェクトをデシリアライズしようとすると、(オブジェクトの正確な状態を構築するために必要な) シリアライズ不可能なスーパー クラスの状態をストリームから復元することはできず、代わりに引数なしを呼び出すことによって復元されます。コンストラクタ。

この問題は、シリアル化できない最初のクラスの引数なしのコンストラクターにアクセスできない場合に発生し、「InvalidClassException: 有効なコンストラクターがありません」という例外がスローされます。

ご存知のように、デフォルトでは各 Java クラスには引数なしのコンストラクターがあります。では、どうしてアクセスできないことがあるのでしょうか。

答えは次のとおりです。デフォルトの引数なしコンストラクターは、引数を持つ他のコンストラクターがクラスで宣言されていない場合にのみ呼び出されます。この場合、引数なしのコンストラクターを呼び出すには、それを個別に宣言する必要があります。

于 2013-06-13T06:02:31.187 に答える