Que se passe-t-il si nous sérialisons et désérialisons deux objets qui font référence l'un à l'autre?

15

Pour être plus clair, voici un exemple rapide:

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;

Que se passe-t-il si nous sérialisons les objets a et b dans un fichier et les désérialisons à partir de ce fichier?

Je pensais que nous obtenions 4 objets, 2 de chacun. Objets identiques mais instances différentes.

Mais je ne sais pas s'il y a autre chose ou si c'est bien ou mal.

Si une technologie devait répondre, pensez à vous baser sur Java.

Je vous remercie.

Seregwethrin
la source

Réponses:

25

Java garde une trace des objets qui ont été écrits dans le flux et les instances suivantes sont écrites sous la forme d'un ID, et non d'un véritable objet sérialisé.

Ainsi, pour votre exemple, si vous écrivez l'instance "a" dans le flux, le flux donne à cet objet un ID unique (disons "1"). Dans le cadre de la sérialisation de "a", vous devez sérialiser "b" et le flux lui donne un autre identifiant ("2"). Si vous écrivez ensuite "b" dans le flux, la seule chose qui est écrite est l'ID, pas l'objet réel.

Le flux d'entrée fait la même chose dans le sens inverse: pour chaque objet qu'il lit dans le flux, il attribue un numéro d'identification en utilisant le même algorithme que le flux de sortie, et ce numéro d'identification fait référence à l'instance d'objet dans une carte. Lorsqu'il voit un objet qui a été sérialisé à l'aide d'un ID, il récupère l'instance d'origine de la carte.

Voici comment les documents de l' API le décrivent:

Plusieurs références à un seul objet sont codées à l'aide d'un mécanisme de partage de référence afin que les graphiques des objets puissent être restaurés dans la même forme que lorsque l'original a été écrit

Ce comportement peut provoquer des problèmes: comme le flux contient une référence matérielle à chaque objet (afin qu'il sache quand remplacer l'ID), vous pouvez manquer de mémoire si vous écrivez beaucoup d'objets transitoires dans le flux. Vous résolvez cela en appelant reset().

parsifal
la source
Donc, il le fera revenir à l'état d'origine après la désérialisation, non? Comme avant la sérialisation avec des références les unes aux autres?
Seregwethrin
1
Oui, vous vous retrouvez avec seulement 2 objets, se référençant.
hectorct
1
Je ne peux pas croire que Java gère cela automatiquement. Je suis impressionné
Cruncher