【问题标题】:Serialization of Java ObjectsJava对象的序列化
【发布时间】:2013-07-09 18:03:31
【问题描述】:

我正在尝试评估在我正在开发的 Java 应用程序中使用序列化对象的有用性。我正在尝试确定以下对于对象序列化实现是否有意义,或者我是否应该自定义构建传输。这是我的场景:

  • 对象将通过 TCP 从一个应用程序传输到另一个应用程序。
  • 序列化对象将是存储在公共库中的类的实例。

示例类:

public class Room implements Serializable {
    // Instance Variables
    private Room roomWithinRoom;
    // ...
}

所以我的问题是,既然我将有几个实例变量引用回 Room 类,我可以使用 Java 序列化来完成 Room 对象的传输吗?如果我能够做到这一点,指针会被保留吗?

例子:

Room mainRoom = new Room();
Room closet = new Room();
mainRoom.addRoom(closet);

如果我发送对象“mainRoom”,它是否也会序列化并发送“closet”实例(在 mainRoom 中保留 roomWithinRoom 实例变量?)

谢谢大家!

【问题讨论】:

    标签: java object networking serialization tcp


    【解决方案1】:

    是的,Java 序列化在这方面做得非常好。也许太好了。我很幸运能写入文件。使用 TCP 一定要在每次写入后调用reset。 Java 将一次性发送整个网络图——您的对象、所有对象引用、所有对象引用等等。一个 writeObject 可以发送千兆字节的数据。但是如果没有重置,如果您编写的下一个对象包含在第一个图中,那么所有将经过的将是对先前发送的对象的引用。任何更新的数据都将被忽略。 (我有没有提到你应该在每个writeObject 之后调用reset?)

    我建议使用 Externalizable 接口。这使您可以更好地控制写入的内容。 (实际上,这是在类的基础上完成的,所以有些类可以是可序列化的,有些可以是可外部化的,没有问题。)这意味着即使类发生了一些变化,您也可以以相同的格式编写。它使您可以跳过不需要的数据,有时将琐碎的对象作为数据原语传递。我还使用版本号,以便新版本的类可以读取旧版本编写的内容。 (这在写入文件时比使用 TCP 更重要。)警告:在读取类时,请注意您刚刚读取的对象引用可能引用任何数据(即引用的对象尚未被读入;您正在查看对象数据去往的未初始化内存。)。

    你可能会摸索一下,但一旦你理解它,它确实会很好地工作。

    【讨论】:

    • 我看不出 TCP 与调用 reset() 有什么关系,而且由于他希望保留引用,我根本不明白您为什么推荐 reset()。您不需要 Externalizable 来克服类更改:对象序列化规范中有一个很大的章节定义了各种更改的兼容性,这比大多数人似乎认为的要广泛得多,即使他们已经阅读过。跨度>
    • @EJP:您希望在一次写入中保留引用。您发送一个对象,它包括其对象图的其余部分。这就是你想要的。更新图中的对象并再次发送一个对象,ObjectOutput 会注意到它已经发送了它们,除了发送一条消息说重复之前的输出之外什么也不做。不会传输任何新数据。
    • @EJP:另一个问题是 ObjectOutput 和 Input 永远不会忘记一个对象。如果你发送一堆不相关的对象,每个都会通过,但它们都会被记住。如果您连接了几个繁忙的小时,这可能会占用两端的大量内存。 (如果你确实重复了一个对象,读者会收到第一个发送的;最新副本的数据不会通过。)
    • @EJP:至于 Externalizable:不,你根本不需要它。我发现它很有用,所以我提到了它。可能只是因为我是个控制狂。
    • 伙计们,我非常感谢您的建议!对于我的具体用例,我的对象只创建一次,在应用范围内不会改变,但我觉得这个讨论非常适合其他可能有不同需求的开发人员。
    【解决方案2】:

    引用将保留在对象图中,并且任何嵌套对象也将被正确序列化,因为它们实现了可序列化接口,并且不会被标记为瞬态。

    我建议不要使用内置的 java 序列化,因为它比其他二进制协议更冗长。此外,序列化/反序列化例程可能在运行时之间发生变化也总是存在潜力

    出于这些原因,我建议ProtoBufs。 ProtoBuf 体积小、速度快,甚至可以用于在 Java 以外的语言中快速构建序列化/反序列化例程,前提是您可以找到该语言的 protobuf“编译器”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多