【问题标题】:Does Java Serialization work for cyclic references?Java 序列化是否适用于循环引用?
【发布时间】:2010-12-20 00:49:23
【问题描述】:

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

对象 A 会正确序列化吗?

评论 #9 here 表示它不起作用。

相比之下,XStream 表示它确实处理循环引用。

【问题讨论】:

  • 当您尝试时会发生什么?
  • 按照我对第 9 条评论的理解,他说的是手动实现可序列化的难度,而不是官方实现的缺陷。
  • 是的,我重读了一遍,我认为我同意它是手工暗示的。
  • 我试过“Java 序列化是否适用于循环引用?”大约一个小时前在谷歌。它现在似乎正在工作。
  • 在 Google 上搜索并不是尝试。编写代码并查看会发生什么是尝试。感谢 Wordle 上的客气话。

标签: java serialization serializable


【解决方案1】:

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

【讨论】:

  • 是否有任何关于它如何工作的文档...我想在我自己的序列化实现中处理这个问题。
【解决方案2】:

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

【讨论】:

【解决方案3】:

是的。

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

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");

    }    
}

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-26
        • 1970-01-01
        相关资源
        最近更新 更多