Что произойдет, если мы сериализуем и десериализуем два объекта, которые ссылаются друг на друга?

15

Чтобы сделать это более понятным, это быстрый пример:

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;

Так что же произойдет, если мы сериализуем объекты a и b в файл и десериализуем из этого файла?

Я думал, что мы получаем 4 объекта, по 2 каждого. Одинаковые объекты, но разные экземпляры.

Но я не уверен, есть ли что-то еще, или это правильно или неправильно.

Если вам нужна какая-то технология, подумайте, пожалуйста, на основе Java.

Спасибо.

Seregwethrin
источник

Ответы:

25

Java отслеживает объекты, которые были записаны в поток, и последующие экземпляры записываются в виде идентификатора, а не фактического сериализованного объекта.

Итак, для вашего примера, если вы напишите экземпляр «a» в поток, поток даст этому объекту уникальный идентификатор (скажем, «1»). Как часть сериализации «a», вы должны сериализовать «b», и поток дает ему другой идентификатор («2»). Если вы затем пишете «b» в поток, единственное, что пишется, это идентификатор, а не фактический объект.

Входной поток делает то же самое в обратном порядке: для каждого объекта, который он читает из потока, он назначает идентификационный номер, используя тот же алгоритм, что и выходной поток, и этот идентификационный номер ссылается на экземпляр объекта на карте. Когда он видит объект, который был сериализован с использованием идентификатора, он получает исходный экземпляр с карты.

Вот как описывают документы API :

Несколько ссылок на один объект кодируются с использованием механизма совместного использования ссылок, так что графики объектов могут быть восстановлены в той же форме, что и при написании оригинала.

Такое поведение может вызвать проблемы: поскольку поток содержит жесткую ссылку на каждый объект (чтобы он знал, когда заменить идентификатор), вы можете исчерпать память, если вы записываете много временных объектов в поток. Вы решаете это по телефону reset().

Парсифаль
источник
Так что после десериализации он вернется в исходное состояние? Как это до сериализации со ссылками друг на друга?
Серегветрин
1
Да, вы получите только 2 объекта, ссылающихся друг на друга.
Гектор
1
Я не могу поверить, что Java обрабатывает это автоматически. Я впечатлен
Cruncher