1

我正在尝试评估在我正在开发的 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 实例变量?)

非常感谢大家!

4

2 回答 2

1

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

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

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

于 2013-07-09T21:02:42.910 回答
0

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

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

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

于 2013-07-09T18:07:36.103 回答