web-dev-qa-db-de.com

Warum ist eine serialisierbare innere Klasse nicht serialisierbar?

Der folgende Code:

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;

    }

}

löst die folgende Ausnahme aus:

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

Ich vermute, die innere Klasse hat ein TestInnerClass.this-Feld, das den privaten Zugriff auf die Felder und Methoden von TestInnerClass ermöglicht. Indem Sie die innere Klasse als statisch deklarieren löst sie , aber was ist, wenn InnerClass diesen Zugriff benötigt? Gibt es eine Möglichkeit, eine nicht statische innere Klasse ohne die einschließende Klasse zu serialisieren, z. durch den Verweis auf die äußere Klasse transient?

edit: Der Zugriff auf die äußere Klasse kann beispielsweise nur vor der Serialisierung erforderlich sein. OK, der Compiler kann das nicht wissen, aber ich dachte, deshalb gibt es das Schlüsselwort transient.

19
tb189

was ist, wenn InnerClass diesen Zugriff benötigt?

Dann benötigt es die äußere Klasseninstanz und muss zusammen mit der inneren Klasse serialisiert werden.

Gibt es eine Möglichkeit, eine nicht statische innere Klasse ohne die einschließende Klasse zu serialisieren, z. indem Sie den Verweis auf die äußere Klasse transient machen?

Was würde passieren, wenn Sie eine solche Klasse deserialisieren und dann versuchen, eine Instanzmethode der äußeren Klasse aufzurufen? Ein NullPointerExceptionname__?

23

wie wäre es, TestInnerClass serialisierbar zu machen?

public class TestInnerClass implements Serializable { }
1
hellojinjie

InnerClass kann nicht serialisiert werden, da Sie zum Instanziieren (wie bei der Deserialisierung erforderlich) einen Verweis auf eine Instanz der äußeren Klasse benötigen

Instanzen innerer Klassen können ohne eine Instanz der äußeren Klasse nicht existieren.

d.h.

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

Wenn Sie eine statische innere Klasse verwenden, ist es möglich, die statische innere Klasse zu serialisieren. Die Instanzen statischer innerer Klassen können eigenständig erstellt werden.

d.h.

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