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

标签 java deserialization standards

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

但是反序列化作为实例方法没有意义。对象状态的任何部分都不应该对从数据构建另一个对象的过程产生任何影响。不存在 foo 类,因此您需要构造 foo 才能构造 foo。

所以我的问题是,标准java是否有一组预先存在的接口(interface)/设施来促进静态反序列化?如果您实现基于实例的方法,那么您的反序列化“就可以”(与任何其他方法一样)适用于任何支持 Java 默认反序列化功能的东西。

是否有内置的东西,可以使用类作为该类对象的工厂,由串行数据构造? Java 中是否有任何东西可以传递一个类,以便该工具知道调用一些静态方法来反序列化,以从其平面形式构造一个对象?

最佳答案

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

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 的行为有点像构造函数,只不过它使用先前序列化的数据来创建对象的实例。扩展类比,你的问题没有意义,因为你会问“为什么使用构造函数创建对象与实例的状态有关系?”。状态问题甚至不适用,因为你甚至没有实例!同样,状态不会与 readObject 一起发挥作用,因为永远无法*使用现有实例反序列化和创建实例。

如果您想更好地控制序列化,如果您想处理一种特殊的方式。通过实现 Externible 并提供 readExternalwriteExternal 实现,您可以更好地控制数据的写出方式。 。

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

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

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

*进入状态的唯一方式是如果您执行一些奇怪的操作,例如从其他实例方法调用 readObject 方法(该方法必须接受 ObjectInputStream),然后您就有了根据现有实例的状态执行反序列化的自定义逻辑。换句话说,对象的状态对反序列化逻辑产生影响的唯一方式就是您明确地以这种方式编写它。再次,正如我之前提到的,这将是非常奇怪的代码,有很多警告并且值(value)极小。

关于java - Java 是否有内置的静态反序列化能力或标准模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30743977/

相关文章:

java - 时间相关的单元测试

java - 正则表达式:必须以 'id-' 开头但不能等于但可以以 'id-bitcoin' 开头

java - Jackson 1.8.5 (for JSON) 不反序列化 : "no such class found"

django - 使用 REST 框架查询 URL 中的参数

c# - 有人更改 Visual Studio 默认的支撑样式吗? - 有标准吗?

java - 在 android.support.design.widget.NavigationView 类中出现错误

java - 为什么 javac 接受编译带有不正确树结构的包声明的类

C++、ECS 和保存/加载

sql - 数据库内的地址标准化

scala - 箭头反模式是 Scala 中的标准吗