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

时间:2013-12-08 19:29:42

标签: java inheritance serialization

我有一个继承树,其中Class A implements Serializable{}
Class B extends A{}Class C extends B{}依此类推至class Z extends Y{}

根据序列化:

“自Class A实现Serializable以来,所有Z的子类都变为'Serializable'”。当我们尝试序列化Z的对象时,所有超类对象都将被序列化。

问题:

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

1 个答案:

答案 0 :(得分:1)

是的,如果C在Z的超类链中,并且想要序列化Z,那么C也将被序列化。您可以使用以下技术之一来避免或解决此问题:

重新排列班级层次结构。

也就是说,使C不再是Z的超类。大概你不想这样做,但考虑到不对C进行序列化的目标,可能是合理的。

控制序列化的C字段。

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

为C。

提供自定义序列化格式

即,使用readObjectwriteObject方法。如果您未从defaultWriteObject方法调用writeObject,则不会发生C的自动字段序列化。同样,请勿在{{1​​}}方法中调用defaultReadObject。请注意,如上所述,这仍然序列化C本身,但避免序列化其部分或全部字段。

为Z。

提供序列化代理

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

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

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