16

例如:对象 A 包含对象 B,对象 B 包含对象 C,对象 C 又包含对象 A。

对象 A 会正确序列化吗?

此处的注释 #9表示它不起作用。

相反,XStream表明它确实处理循环引用。

4

5 回答 5

18

是的,默认的 Java 序列化适用于循环引用。当您序列化对象 C 时,该字段将包含对已序列化对象 A 的反向引用,而不是再次对其进行序列化。

于 2009-11-24T19:53:23.810 回答
3

是的,Java 序列化适用于循环引用,请阅读此处了解更多信息,以帮助您了解 Java 序列化可以做什么。

于 2009-11-24T20:04:15.813 回答
2

是的,它确实。

我做了这个非常非常简单的测试,至少它完成了序列化。我认为它是正确的,但是您可以通过一些额外的行来检查它。

import java.io.*;
class A implements Serializable { B b; }
class B implements Serializable { C c; }
class C implements Serializable { A a; }
class Test {
    public static void main( String [] args ) throws IOException {
        A a = new A();
        a.b = new B();
        a.b.c = new C();
        a.b.c.a = a;
        new ObjectOutputStream( new ByteArrayOutputStream( ) ).writeObject( a );
        System.out.println("It works");

    }    
}
于 2009-11-24T20:42:47.890 回答
0

如果您将对象序列化为 XML,您实际上可以直接查看引用。子对象只被序列化一次。对已经序列化的子对象的任何引用(序列化结构中的任何位置)都将简单地指向文件中的该对象。

不过,序列化循环引用可能会有点混乱,因此您可能希望尽可能避免使用它们。

于 2009-11-24T20:28:36.360 回答
0

是的 - 有一个很大的警告:您不能在对象图包含循环的情况下使用 writeReplace/readResolve。原因在这里解释。

这意味着循环对象图在一般情况下与使用 Josh Bloch 的 SerializationProxy 模式不兼容。如果您对对象图中后代节点的结构有足够的了解以在序列化时删除反向引用并在反序列化时替换它们,您有时可以解决此问题。但这通常是不可能的。这个问题已经在 J​​DK 错误报告中多次提出,但都被耸了耸肩。我认为鉴于默认 Java 序列化的漏洞,这种态度非常令人恼火。我们要实现自己的通用对象序列化解决方案,这是一项艰巨的任务,但存在开源替代方案。

我遇到的一个似乎质量相当高的软件是 Esoteric Software 的Kryo

于 2022-01-25T03:03:59.327 回答