简体   繁体   English

序列化 - 使用ObjectStreamField [] serialPersistentFields有什么好处?

[英]Serialization - What is the advantage of using ObjectStreamField [] serialPersistentFields?

For class that implements Serializable interface there are 2 ways to define what specific fields get streamed during the serialization: 对于实现Serializable接口的类,有两种方法可以定义在序列化期间流式传输的特定字段:

  1. By default all non-static, non-transient fields that implement Serializable are preserved. 默认情况下,将保留实现Serializable所有非静态非瞬态字段。
  2. By definning ObjectStreamField [] serialPersistentFields and explicitly declaring the specific fields saved. 通过定义ObjectStreamField [] serialPersistentFields并明确声明保存的特定字段。

I wonder, what is the advantage of the second method except for the ability to define specific fields order? 我想知道,除了定义特定字段顺序的能力之外,第二种方法的优点是什么?

Luckily, I'm actually writing this up right now.... Besides the advantages mentioned (and I don't know much about unshared), writing your own output format seems to have the following advantages: 幸运的是,我现在正在写这个....除了提到的优点(我不太了解非共享),编写自己的输出格式似乎具有以下优点:

  • Allows conditional output (different uses for serialization, such as persistence and copying, can serialize different parts of the object). 允许条件输出(序列化的不同用途,例如持久性和复制,可以序列化对象的不同部分)。
  • Should be faster, use less memory, and in some cases use less disk than the default mechanism (this is from Bloch's Effective Java 2 ). 应该更快,使用更少的内存,并且在某些情况下使用比默认机制更少的磁盘(这来自Bloch的Effective Java 2 )。
  • Allows you to rename variables in a serialized class while maintaining backwards-compatibility. 允许您重命名序列化类中的变量,同时保持向后兼容性。
  • Allows you to access data from deleted fields in a new version (in other words, change the internal representation of your data while maintaining backwards-compatibility). 允许您从新版本中的已删除字段访问数据(换句话说,更改数据的内部表示,同时保持向后兼容性)。

I've seen the documentation you're quoting, and mentioning just those 2 options is a bit misleading and leaves quite a bit out: you can customize your serialization format in 2 ways, by using the ObjectOutput/InputStream interface to write and read fields in a particular order (described in Bloch), and using the PutField and GetField classes to write and read fields by name. 我已经看到了你引用的文档,并且只提到这两个选项有点误导,并且有很多不足之处:你可以通过两种方式自定义序列化格式,方法是使用ObjectOutput / InputStream接口来编写和读取字段按特定顺序(在Bloch中描述),并使用PutField和GetField类按名称写入和读取字段。 You can use serialPersistentFields as your quote mentions to extend this second method, but it's not required unless you need to read or write data with a name which is not a member variable name. 您可以使用serialPersistentFields作为引用提及扩展第二种方法,但除非您需要读取或写入名称不是成员变量名称的数据,否则不需要它。

There's a 3rd way to control format as well, using the Externizable interface, though I haven't explored that much. 使用Externizable接口也有第三种控制格式的方法,尽管我没有那么多探索。 And some of the advantages can also be gotten through Serialization Proxies (see Bloch). 并且还可以通过序列化代理获得一些优点(参见Bloch)。

Anyone feel free to correct me on details if I missed anything. 如果我错过任何东西,任何人都可以随时纠正我的细节。

The 'advantage' is that it does what it says in the Javadoc: defines which fields are serialized. “优势”是它在Javadoc中执行的操作:定义哪些字段是序列化的。 Without it, all non-transient non-static fields are serialized. 没有它,所有非瞬态非静态字段都被序列化。 Your choice. 你的选择。

The advantage is you can conditionally populate ObjectStreamField at runtime albeit only once per JVM lifecycle to determine which fields should be serialized. 优点是您可以在运行时有条件地填充ObjectStreamField,尽管每个JVM生命周期只有一次,以确定应该序列化哪些字段。

private static final ObjectStreamField [] osf;
static {
    //code to init osf
}

In serialPersistentFields you can specify fields that are not necessarily present in the class anymore. serialPersistentFields您可以指定不再存在于类中的字段。

See for example the jdk class java.math.BigInteger , where several fields are read and written which don't exist anymore in the class. 例如,参见jdk类java.math.BigInteger ,其中读取和写入的几个字段在类中不再存在。 These obsolete fields are still read and written for compatibility with older versions. 为了与旧版本兼容,仍然会读取和写入这些过时的字段。 The reading and writing of these fields is handled by the readObject() and writeObject() methods. 读取和写入这些字段由readObject()writeObject()方法处理。

See also http://docs.oracle.com/javase/7/docs/platform/serialization/spec/serial-arch.html#6250 另见http://docs.oracle.com/javase/7/docs/platform/serialization/spec/serial-arch.html#6250

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

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