Was passiert, wenn wir zwei Objekte, die aufeinander verweisen, serialisieren und deserialisieren?

15

Um es klarer zu machen, ist dies ein kurzes Beispiel:

class A implements Serializable { public B b; }
class B implements Serializable { public A a; }
A a = new A();
B b = new B();
a.b = b;
b.a = a;

Was passiert also, wenn wir a- und b-Objekte in eine Datei serialisieren und aus dieser Datei deserialisieren?

Ich dachte wir bekommen 4 Objekte, 2 von jedem. Identische Objekte, aber unterschiedliche Instanzen.

Aber ich bin mir nicht sicher, ob es noch etwas gibt oder ob es richtig oder falsch ist.

Wenn eine Technologie zur Beantwortung benötigt wird, denken Sie bitte an Java.

Vielen Dank.

Seregwethrin
quelle

Antworten:

25

Java verfolgt die Objekte, die in den Stream geschrieben wurden, und nachfolgende Instanzen werden als ID und nicht als tatsächlich serialisiertes Objekt geschrieben.

Wenn Sie also in Ihrem Beispiel die Instanz "a" in den Stream schreiben, gibt der Stream diesem Objekt eine eindeutige ID (sagen wir "1"). Im Rahmen der Serialisierung von "a" müssen Sie "b" serialisieren, und der Stream gibt ihm eine andere ID ("2"). Wenn Sie dann "b" in den Stream schreiben, wird nur die ID und nicht das eigentliche Objekt geschrieben.

Der Eingabestream macht dasselbe in umgekehrter Reihenfolge: Für jedes Objekt, das er aus dem Stream liest, weist er eine ID-Nummer zu, die denselben Algorithmus wie der Ausgabestream verwendet, und diese ID-Nummer verweist auf die Objektinstanz in einer Zuordnung. Wenn ein Objekt angezeigt wird, das mit einer ID serialisiert wurde, wird die ursprüngliche Instanz von der Map abgerufen.

So beschreiben es die API-Dokumente :

Mehrere Verweise auf ein einzelnes Objekt werden mithilfe eines Mechanismus zur gemeinsamen Nutzung von Verweisen codiert, sodass Diagramme von Objekten in der gleichen Form wiederhergestellt werden können, wie sie beim Schreiben des Originals vorhanden waren

Dieses Verhalten kann zu Problemen führen: Da der Stream einen festen Verweis auf jedes Objekt enthält (damit er weiß, wann die ID ersetzt werden muss), kann der Arbeitsspeicher knapp werden, wenn Sie viele transiente Objekte in den Stream schreiben. Sie lösen das, indem Sie anrufen reset().

Parsifal
quelle
Es wird also nach der Deserialisierung wieder in den ursprünglichen Zustand versetzt, oder? Wie ist es vor der Serialisierung mit Verweisen aufeinander?
Seregwethrin,
1
Ja, Sie haben nur 2 Objekte, die sich gegenseitig referenzieren.
Hectorct
1
Ich kann nicht glauben, dass Java dies automatisch erledigt. Ich bin beeindruckt
Cruncher