web-dev-qa-db-ja.com

なぜシリアライズ可能な内部クラスがシリアライズできないのですか?

次のコード:

public class TestInnerClass {

    public static void main(String[] args) throws IOException {
        new TestInnerClass().serializeInnerClass();
    }

    private void serializeInnerClass() throws IOException {
        File file = new File("test");
        InnerClass inner = new InnerClass();
        new ObjectOutputStream(new FileOutputStream(file)).writeObject(inner);
    }

    private class InnerClass implements Serializable {

        private static final long serialVersionUID = 1L;

    }

}

次の例外をスローします。

Exception in thread "main" Java.io.NotSerializableException: TestInnerClass

内部クラスには、TestInnerClassのフィールドとメソッドへのプライベートアクセスを許可するTestInnerClass.thisフィールドがあると思います。内部クラスstatic それを解決する を宣言しますが、InnerClassがこのアクセスを必要とする場合はどうなりますか?囲むクラスなしで非静的内部クラスをシリアル化する方法はありますか?外部クラスtransient

編集:たとえば、外部クラスへのアクセスは、シリアル化の前にのみ必要になる可能性があります。 OK、コンパイラはそれを知ることができませんが、それがtransientキーワードが存在する理由だと思いました。

23
tb189

innerClassがこのアクセスを必要とする場合はどうなりますか?

次に、外部クラスインスタンスが必要であり、内部クラスと共にシリアル化する必要があります。

囲むクラスなしで非静的内部クラスをシリアル化する方法はありますか?外部クラスへの参照を一時的にすることによって?

いいえ。そのようなクラスを逆シリアル化してから、外部クラスのインスタンスメソッドを呼び出そうとするとどうなりますか。 NullPointerException

26

testInnerClassをシリアライズ可能にしてみませんか?

public class TestInnerClass implements Serializable { }
2
hellojinjie

インスタンス化するには(逆シリアル化中に必要な場合)、外部クラスのインスタンスへの参照が必要なため、InnerClassをシリアル化できません

内部クラスのインスタンスは、外部クラスのインスタンスなしでは存在できません。

つまり

OuterClass o = new OuterClass();
OuterClass.InnerClass o_i = o.new InnerClass();

静的内部クラスを使用する場合、静的内部クラスをシリアル化することが可能になります。静的内部クラスのインスタンスはスタンドアロンで作成できます。

つまり

OuterClass o = new OuterClass();
OuterClass.InnerClass i = new OuterClass.InnerClass();
2
Mathew