次のコード:
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
キーワードが存在する理由だと思いました。
innerClassがこのアクセスを必要とする場合はどうなりますか?
次に、外部クラスインスタンスが必要であり、内部クラスと共にシリアル化する必要があります。
囲むクラスなしで非静的内部クラスをシリアル化する方法はありますか?外部クラスへの参照を一時的にすることによって?
いいえ。そのようなクラスを逆シリアル化してから、外部クラスのインスタンスメソッドを呼び出そうとするとどうなりますか。 NullPointerException
?
testInnerClassをシリアライズ可能にしてみませんか?
public class TestInnerClass implements Serializable { }
インスタンス化するには(逆シリアル化中に必要な場合)、外部クラスのインスタンスへの参照が必要なため、InnerClassをシリアル化できません
内部クラスのインスタンスは、外部クラスのインスタンスなしでは存在できません。
つまり
OuterClass o = new OuterClass();
OuterClass.InnerClass o_i = o.new InnerClass();
静的内部クラスを使用する場合、静的内部クラスをシリアル化することが可能になります。静的内部クラスのインスタンスはスタンドアロンで作成できます。
つまり
OuterClass o = new OuterClass();
OuterClass.InnerClass i = new OuterClass.InnerClass();