如果我们序列化和反序列化两个互相引用的对象会发生什么?


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进行思考。

谢谢。

Answers:


25

Java跟踪已写入流中的对象,随后的实例作为ID写入,而不是实际的序列化对象。

因此,以您的示例为例,如果您将实例“ a”写入流中,则该流为该对象赋予唯一的ID(比方说“ 1”)。作为“ a”序列化的一部分,您必须序列化“ b”,并且流为它提供另一个id(“ 2”)。如果然后在流中写入“ b”,则唯一写入的是ID,而不是实际对象。

输入流相反地执行相同的操作:对于从流中读取的每个对象,它使用与输出流相同的算法分配一个ID号,并且该ID号引用映射中的对象实例。当看到使用ID序列化的对象时,它将从映射中检索原始实例。

这是怎样的API文档描述它:

使用引用共享机制对单个对象的多个引用进行编码,以便可以将对象的图恢复为与编写原始图时相同的形状

此行为可能会引起问题:由于流对每个对象都具有硬引用(这样它就知道何时替换ID),因此,如果向流中写入大量临时对象,则可能会耗尽内存。您可以通过致电解决此问题reset()


因此,它将在反序列化后使其恢复到原始状态,对吗?像在序列化之前互相引用一样吗?
塞雷格斯琳

1
是的,您最终只有两个对象,彼此引用。
2012年

1
我不敢相信Java会自动处理这个问题。我印象深刻
Cruncher

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.