java - 停止java中继承树中某些类类型的序列化

标签 java inheritance serialization

我有一个继承树,其中
A 类实现 Serializable{}
B 类扩展 A{}C 类扩展 B{} 等等直到 Z 类扩展 Y{}

根据序列化:

“由于 A 类 实现了 Serializable,所有直到 Z 的子类都变成了‘Serializable’”。当我们尝试序列化 Z 的对象时,所有父类(super class)对象都将被序列化。

问题:

当我序列化Z类的对象时,如何避免C类的对象被序列化?

最佳答案

对,如果 C 在 Z 的父类(super class)链中,而你序列化 Z,那么 C 也会被序列化。您可以使用以下技术之一避免或解决此问题:

重新排列类层次结构。

也就是说,使 C 不再是 Z 的父类(super class)。大概您不想这样做,但考虑到不序列化 C 的目标,考虑这一点可能是合理的。

控制被序列化的C的字段。

您可以将未序列化的 C 字段标记为 transient。也许更好的方法是在 C 中声明一个 serialPersistentFields 数组,它可能为空,包含要序列化的 C 字段的名称。这可能比将您不想序列化的字段标记为 transient 更容易或更易于维护。注意C仍然是序列化的,但是可以省略其字段的序列化。

为 C 提供自定义序列化格式。

即使用readObjectwriteObject方法。如果您不从 writeObject 方法中调用 defaultWriteObject,那么 C 的自动字段序列化都不会发生。同样,不要从 readObject 方法中调用 defaultReadObject。请注意,如上所述,这仍然会序列化 C 本身,但会避免序列化其部分或全部字段。

为 Z 提供序列化代理。

为 Z 提供一个 writeReplace 方法。writeReplace 方法安排事情以便当有人请求序列化 Z 时,一个不同的对象(称为例如 ZProxy)被序列化。让您的 writeReplace 方法构造一个 ZProxy 实例,其中恰好包含您要序列化的 Z 中的数据,并返回该 ZProxy 实例。该实例将被序列化以代替 Z 实例。 ZProxy 不必与 Z 在同一类层次结构中;它可以完全无关。当 ZProxy 实例被反序列化时,确保 ZProxy 有一个 readResolve 方法,该方法从 ZProxy 中的数据构造一个 Z 实例并返回 Z 实例。

有关序列化代理的更多信息,请参阅 Bloch,Effective Java,第 78 项。

您可能还想提供一个抛出异常的 Z.readObject 方法,以防止有人伪造一个声称包含 Z 的序列化实例的序列化字节流,然后将其反序列化。这强制了只有 ZProxy 实例出现在序列化字节流中的约束,而不是实际的 Z 实例。

关于java - 停止java中继承树中某些类类型的序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20457951/

相关文章:

Java 事件处理程序命名约定

c# - 比较对象并确定通用类型

Swift 4 泛型,引用自身

c# - 将对象保存到没有序列化属性的文件的最简单方法是什么?

java - 执行自定义 native 查询时无法提取 ResultSet

java - 将电话号码(手机或固定电话)拆分为国家代码、区号和号码

php - 检查字符串是否被序列化?

ruby-on-rails - 编辑表单中的序列化哈希?

java - Spring Boot 和 JPA 存储库 — 如何按 ID 过滤 GET

C++ 多模板纯虚继承