简体   繁体   English

Java对象的序列化

[英]Serialization of Java Objects

I'm trying to evaluate the usefulness of using Serialized objects in a Java application I'm developing. 我正在尝试评估正在开发的Java应用程序中使用序列化对象的有用性。 I'm trying to determine if the following makes sense for an Object-serialization implementation, or if I should custom-build the transport. 我试图确定以下内容对于对象序列化实现是否有意义,或者是否应该自定义构建传输。 Here's my scenario: 这是我的情况:

  • Objects will be transported over TCP from one application to another. 对象将通过TCP从一个应用程序传输到另一个应用程序。
  • The serialized object will be an instance of a class stored in a common library. 序列化的对象将是存储在公共库中的类的实例。

Sample Class: 样本类别:

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

So my question is that since I will have several instance variables that reference back to the Room class, can I use Java serialization to accomplish the transfer of Room objects? 所以我的问题是,由于我将有几个实例变量引用回Room类,因此我可以使用Java序列化来完成Room对象的传输吗? If I am able to accomplish this, will the pointers be preserved? 如果我能够做到这一点,将保留指针吗?

Example: 例:

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

If I send over the object "mainRoom," will it also serialize and send the "closet" instance (preserving the roomWithinRoom instance variable in mainRoom?) 如果我发送对象“ mainRoom”,它还会序列化并发送“壁橱”实例(在mainRoom中保留roomWithinRoom实例变量吗?)

Thanks a bunch, everyone! 谢谢大家!

Yes, Java serialization does this really well. 是的,Java序列化确实做得很好。 Maybe too well. 也许太好了。 I've had great luck writing to files. 我很幸运写文件。 With TCP be sure to call reset after each write. 使用TCP时,请确保在每次写入后调用reset Java will send a whole network graph in one go--your object, all the objects references, all they reference, and so on. Java将一次性发送整个网络图-您的对象,所有对象引用,它们引用的所有对象,依此类推。 One writeObject can send gigabytes of data. 一个writeObject 可以发送千兆字节的数据。 But without reset, if the next object you write was included in the first graph, all that will go across will be a reference to the previously sent object. 但是,如果不进行重置,则如果您编写的下一个对象包含在第一个图形中,则所有遇到的操作将是对先前发送的对象的引用。 Any updated data will be ignored. 任何更新的数据将被忽略。 (Did I mention you should call reset after each writeObject ?) (我有没有提到您应该在每个writeObject之后调用reset ?)

I'd suggest using the Externalizable interface. 我建议使用Externalizable接口。 This gives you a bit more control over what gets written. 这使您可以更好地控制所写内容。 (Actually, this is done on a class basis, so some classes can be Serializable and some Externalizable with no problem.) This means you can write in the same format even when the class changes a bit. (实际上,这是在类的基础上完成的,因此某些类可以序列化,而某些可外部化则没有问题。)这意味着即使类有所更改,您也可以使用相同的格式编写。 It lets you skip data you don't need, and sometimes pass trivial objects as data primitives. 它使您可以跳过不需要的数据,有时还可以将琐碎的对象作为数据基元传递。 I also use version numbers so newer versions of the class can read stuff written by older versions. 我还使用版本号,以便该类的新版本可以读取旧版本编写的内容。 (This is a bit more important when writing to files than with TCP.) A warning: when reading a class, be aware that the object reference you just read may not reference any data (that is, the referenced object has not be read in yet; you're looking at unitialized memory where the object's data will go.). (与TCP相比,写入文件时这要重要得多。)警告:读取类时,请注意,您刚刚读取的对象引用可能不会引用任何数据(即,未读取被引用的对象)还没有;您正在查看对象数据移至的统一存储器。)

You'll probably fumble around with this a bit, but it does work really well once you understand it. 您可能会对此感到有些困惑,但是一旦您了解了它,它的确会很好地工作。

References will be preserved within the object graph, and any nested objects will also be serialized correctly given they implement the serializable interface, and are not marked transient. 引用将保留在对象图中,并且任何嵌套的对象只要实现了可序列化的接口,也将被正确序列化,并且不会标记为瞬态。

I advise against built in java serialization as it is more verbose than other binary protocols. 我建议不要使用内置的Java序列化,因为它比其他二进制协议更冗长。 Also there is always the potential that serialization/deserialization routines could change between runtimes. 同样,序列化/反序列化例程在运行时之间总是可能会发生变化。

For these reasons, I suggest ProtoBufs . 由于这些原因,我建议使用ProtoBufs ProtoBuf is small, fast, and can even be used to quickly build serialization/deserialization routines in languages other than Java, given you find a protobuf "compiler" for that language. ProtoBuf体积小,速度快,并且甚至可以用于以Java以外的其他语言快速构建序列化/反序列化例程,前提是您找到了该语言的protobuf“编译器”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM