Java是否具有静态反序列化的内置能力或标准模式?

时间:2015-06-09 22:32:58

标签: java deserialization standards

序列化作为实例方法是有意义的 - 对象可能合理地能够自行序列化。对象应该只处于有效状态,并且允许对象的所有有效状态进行序列化。这个想法没有任何效果。

但反序列化作为实例方法没有意义。对象状态的任何部分都不应该任何影响从数据构造另一个对象的过程。没有类foo,所以你需要一个构造的foo来构造一个foo。

所以我的问题是,标准java是否有一套预先存在的接口/设施来促进静态反序列化?如果您实现基于实例的方法,那么您的反序列化"只是工作" (与任何事情一样),任何与Java的默认反序列化能力相关的东西。

是否内置了任何内容,使用类作为该类对象的工厂,是否使用串行数据构建? Java中有什么东西我可以传递一个类,这样这个工具就会知道调用一些静态方法来反序列化从扁平形式构造一个对象吗?

1 个答案:

答案 0 :(得分:2)

反序列化实例方法readObject是私有的。没有办法从外面打电话。你可以从你的一个实例方法中调用它,但这很奇怪,我一直在质疑你为什么要这样做。你说:

  

对象状态的任何部分都不应该对从数据构造另一个对象的过程产生任何影响。

是的,但我不明白为什么你认为这会是一个问题。在你已经创建的实例上,你无法从外部调用readObject(除非你从其他一些公共方法中调用它,正如我所说,有点不确定)。反序列化时,很可能会使用ObjectInputStream,它将使用no-args构造函数创建新实例,然后使用流中的数据来水合该对象(当您调用{{1}时})。因此,不存在影响反序列化的实例状态的问题,因为您获得的是从序列化数据创建的实例(如ObjectInputStream#readObject,但您将把它转换为具体类型)。

实际上,Object的行为有点像构造函数,除了它使用以前序列化的数据来创建对象的实例。扩展这个类比,你的问题没有意义,因为你会问"为什么使用构造函数创建一个对象与实例的状态有关?"。国家的问题甚至不适用,因为你甚至没有实例!同样,状态不会与readObject发挥作用,因为永远不会 * 反序列化并使用现有实例创建实例。

如果您希望更好地控制序列化,可以在类中覆盖readObjectreadObject,如果您想以特殊方式处理事物。通过实施writeObject并为SerializableExternizable提供实施,您可以更好地控制 数据的写入方式。

在你的第二个问题中,你想知道"是什么"是调用readExternal。 "东西"是reflection; writeExternal会检查该类是否有readObject方法。如果您提供了自己的实现,它会调用它。否则它将调用ObjectInputStream(其中包含默认序列化的逻辑)。

对于反序列化的内置工厂,没有任何东西,因为标准的序列化/反序列化方法似乎运行良好,所以我真的感觉不到需要。

如果您想了解更多相关信息,我建议您查看serialization specification,全面深入地了解Java如何处理序列化问题,特别是针对您的特定问题Object Input Classes。< / p>

* 状态进入它的唯一方法就是你做了一些奇怪的事情,比如从其他一些实例方法调用readObject方法(必须接受defaultReadObject }),然后你有自定义逻辑,根据现有实例的状态执行反序列化。换句话说,对象的状态与反序列化逻辑有任何关系的唯一方法是,如果你明确地以那种方式写。再次,正如我之前提到的那样,这将是非常奇怪的代码,有很多警告和最小的价值。