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

Does Java have builtin ability or standard patterns for static deserialization?

序列化作为实例方法是有意义的——一个对象可能能够合理地序列化自身。对象只应处于有效状态,并且对象的所有有效状态都应允许序列化。这个想法没有什么不对的。

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

所以我的问题是,标准 java 是否有一组预先存在的 interfaces/facilities 来促进静态反序列化?如果您实施基于实例的方法,您的反序列化 "just works"(就像任何事情一样)与任何与 Java 的默认反序列化能力一起工作的东西。

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

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

No part of an object's state should have any bearing on the process of constructing another object from data.

是的,但我不明白你为什么认为这是个问题。您无法从外部调用 readObject(除非您从其他 public 方法调用它,正如我所说,这有点不确定)在您已经创建的实例上。反序列化时,您很可能会使用 ObjectInputStream,它将使用无参数构造函数创建一个新实例,然后使用流中的数据对该对象进行水合(当您调用 ObjectInputStream#readObject).所以不存在影响反序列化的实例状态的问题,因为你得到的是一个实例序列化数据创建的实例(如Object,但你随后将投射它到具体类型)。

实际上,readObject 的行为有点像构造函数,只是它使用先前序列化的数据来创建对象的实例。扩展类比,您的问题没有意义,因为您会问 "Why does creating an object using the constructor have anything to do with the state of the instance?"。状态问题甚至不适用,因为您甚至没有实例!同样,状态不会与 readObject 一起发挥作用,因为永远无法 * 反序列化并使用 现有 实例创建实例。

如果您想更好地控制序列化,您可以在 class 中覆盖 Serializable 中的 readObjectwriteObject,如果您想以特殊方式处理事情.通过实现 Externizable 并提供 readExternalwriteExternal 的实现,您可以更好地控制 如何 写出数据。

在你的第二个问题中,你想知道调用 readObject 的 "something" 是什么。 "something" 是 reflectionObjectInputStream 将检查 class 是否有 readObject 方法。如果您提供了自己的实现,它将调用它。否则它将调用 defaultReadObject(其中包含默认序列化的逻辑)。

就用于反序列化的内置工厂而言,没有任何东西,而且我也没有真正觉得需要什么,因为标准 serialization/deserialization 方法似乎很有效。

如果您想了解更多这方面的信息,我建议您查看 serialization specification for a comprehensive and in-depth view of how Java tackles serialization, and specifically Object Input Classes 以了解您的特定问题。

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