26

サブクラスのみSerializableがインターフェースを実装しています。

import java.io.*;

public class NewClass1{

    private int i;
    NewClass1(){
    i=10;
    }
    int getVal() {
        return i;
    }
    void setVal(int i) {
        this.i=i;
    }
}

class MyClass extends NewClass1 implements Serializable{

    private String s;
    private NewClass1 n;

    MyClass(String s) {
        this.s = s;
        setVal(20);
    }

    public String toString() {
        return s + " " + getVal();
    }

    public static void main(String args[]) {
        MyClass m = new MyClass("Serial");
        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serial.txt"));
            oos.writeObject(m); //writing current state
            oos.flush();
            oos.close();
            System.out.print(m); // display current state object value
        } catch (IOException e) {
            System.out.print(e);
        }
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("serial.txt"));
            MyClass o = (MyClass) ois.readObject(); // reading saved object
            ois.close();
            System.out.print(o); // display saved object state
        } catch (Exception e) {
            System.out.print(e);
        }
    }
}

ここで気づいたことの 1 つは、親クラスがシリアル化されていないことです。NotSerializableException次に、実際にスローしなかったのはなぜですか

出力

Serial 20
Serial 10

Serializationまた、出力は ととは異なりますDe-serialization。親クラスが実装されていないためSerializableです。しかし、誰かが私に説明すると、オブジェクトのシリアル化と逆シリアル化中に何が起こるか. どのように値を変更しますか? 私は理解できません。また、プログラムでコメントを使用しました。ですから、どこかで間違っていたら教えてください。

4

3 に答える 3

33

Serializable javadocによると

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

また、シリアライズされるクラスがシリアライズ可能でない場合にのみ、シリアライゼーション例外がスローされます。シリアル化できない親を持つことは問題ありません (引数のないコンストラクターがある限り)。オブジェクト自体はシリアライズ可能ではなく、すべてがそれを拡張します。上記の引用は、値フィールドに異なる値を取得する理由も説明しています-値フィールドを10に設定する親クラスの引数なしコンストラクターが設定されています-フィールドは(シリアル化できない)親に属しているため、その値はありませんストリームへの書き込み/ストリームからの読み取り。

于 2012-12-26T15:11:05.557 に答える
5

MyClass がシリアル化できないクラスのオブジェクトへの参照を保持している場合、実行時に NotSerializable 例外が発生します。テストするには、NewClass1 のオブジェクトへの参照を保持するように MyClass を変更します。もう一度実行すると、例外がスローされます。

逆シリアル化とは、基本的に、シリアル化可能なクラスのインスタンスを作成し、そのプロパティを復元することです。このプロセス中に、シリアライズ可能なクラスのコンストラクターは呼び出されません。代わりに、最初のシリアル化不可能なスーパー クラスの no arg コンストラクタが呼び出されます。

あなたの場合、NewClass1 の引数なしのコンストラクターは、そのインスタンス変数 i に 10 を割り当てます。したがって、逆シリアル化中に、20 ではなく 10 が出力されます。

于 2012-12-26T15:12:27.213 に答える
0

私はそれをテストしていませんがNotSerializableException、基本クラスのインスタンスをシリアル化すると、. ではないメンバーがクラスに含まれている場合も同様Serializableです。

つまり、オブジェクトを作成しNewClass1 nc1 = new NewClass1();て obj nc1 をシリアル化しようとすると、必要な例外が発生します。

于 2012-12-26T15:09:23.363 に答える