Cosa succede se serializziamo e deserializziamo due oggetti che fanno riferimento l'uno all'altro?


15

Per renderlo più chiaro, questo è un rapido esempio:

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;

Quindi cosa succede se serializziamo gli oggetti aeb in un file e deserializziamo da quel file?

Pensavo avessimo 4 oggetti, 2 di ciascuno. Oggetti identici ma istanze diverse.

Ma non sono sicuro se c'è qualcos'altro o è giusto o sbagliato.

Se è necessaria una tecnologia per rispondere, ti preghiamo di pensare basato su Java.

Grazie.

Risposte:


25

Java tiene traccia degli oggetti che sono stati scritti nel flusso e le istanze successive vengono scritte come ID, non come un vero oggetto serializzato.

Quindi, per esempio, se scrivi l'istanza "a" nello stream, lo stream dà a quell'oggetto un ID univoco (diciamo "1"). Come parte della serializzazione di "a", devi serializzare "b" e il flusso gli fornisce un altro id ("2"). Se poi scrivi "b" nello stream, l'unica cosa che viene scritta è l'ID, non l'oggetto reale.

Il flusso di input fa la stessa cosa al contrario: per ogni oggetto che legge dal flusso, assegna un numero ID usando lo stesso algoritmo del flusso di output e quel numero ID fa riferimento all'istanza dell'oggetto in una mappa. Quando vede un oggetto serializzato utilizzando un ID, recupera l'istanza originale dalla mappa.

Ecco come lo descrivono i documenti API :

I riferimenti multipli a un singolo oggetto sono codificati utilizzando un meccanismo di condivisione dei riferimenti in modo che i grafici degli oggetti possano essere ripristinati nella stessa forma di quando è stato scritto l'originale

Questo comportamento può causare problemi: poiché il flusso contiene un riferimento reale a ciascun oggetto (in modo che sappia quando sostituire l'ID), è possibile esaurire la memoria se si scrivono molti oggetti transitori nel flusso. Lo risolvi chiamando reset().


Quindi lo farà tornare allo stato originale dopo la deserializzazione, giusto? Com'è prima della serializzazione con riferimenti reciproci?
Seregwethrin,

1
Sì, finisci con solo 2 oggetti, facendo riferimento a vicenda.
hectorct

1
Non posso credere che Java lo gestisca automaticamente. Sono impressionato
Cruncher il

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.