当前位置: 首页 > 面试题库 >

Java序列化-java.io.InvalidClassException本地类不兼容

丌官承
2023-03-14
问题内容

我有一个公共类,该类实现了Serializable,并由其他多个类进行了扩展。只有那些子类曾经被序列化过-从来没有超类。

超类已定义了serialVersionUID。

我不确定是否重要,但是它没有标记为私有,而是仅具有默认保护-您可能会说它是受软件包保护的

static final long serialVersionUID = -7588980448693010399L;

但是,超类或任何子类均未实现readObject或writeObject,并且这些子类均未明确定义serialVersionUID。我认为在超类中定义一个就足够了。

尽管如此,就可以读回以前序列化的对象,直到在超类中添加了新的实例变量List /
ArrayList以及新方法,并在其子类之一中添加了一些私有实例变量为止,一切都很好。

现在,当尝试回读先前序列化的对象时,将引发异常。与此类似的一个:

com.SomeCompany.SomeSubClass; local class incompatible: stream classdesc serialVersionUID = 1597316331807173261, local class serialVersionUID = -3344057582987646196

我认为这是由于默认的serialVersionUID(由于我未在任何子类中声明一个)而使用的,现在已由于超类和一个子类的更改而发生了更改。

关于如何摆脱这一困境的建议将不胜感激。我假设我需要实现readObject和writeObject,但是除了调用defaultReadObject()和defaultWriteObject()之外,我不确定自己需要做什么。我也不知道是否需要向所有子类添加serialVerisonUID,还是每个子类都需要实现readObject和writeObject,或者我是否可以只在超类中实现一次(假设根本不需要)。


问题答案:

@DanielChapman很好地解释了serialVersionUID,但没有解决方案。解决方法是:serialver在所有
类上运行该程序。将这些serialVersionUID值放在 当前
的类版本中。只要当前的类与旧版本在串行上兼容,就可以了。(注意以后的代码: 所有 类上都应 始终 有一个)serialVersionUID
__Serializable

如果新版本与序列 兼容,那么您需要对自定义readObject实现做一些魔术(仅writeObject当您尝试编写与旧代码兼容的
类数据时才需要自定义)。一般来说,添加或删除类字段不会使类序列不兼容。更改现有字段的类型通常会。

当然,即使新类
串行兼容,您仍可能需要自定义readObject实现。如果您要填写从旧版本的类中保存的数据中缺少的任何新字段,则可能需要这样做(例如,您有一个新的List字段,要在加载旧的类数据时将其初始化为空列表)。



 类似资料:
  • 问题内容: 我创建客户端和服务器,然后在添加客户端类的序列化的目的,然后简单地刚走到客户在我的硬盘驱动器的文件夹,并将其粘贴到服务器correponding位置,都和分别。 它在我自己的笔记本电脑上运行良好,但是当我想在其他系统上继续工作时,当我打开项目文件夹并且客户端尝试连接到服务器后,出现以下错误: 到底是怎么回事?是因为我使用旧版本的IDE运行程序吗? 问题答案: 如果一个类未在代码中显式定

  • 问题内容: 我有一个对象,即时通讯读取和写入,并从和。我不断收到Java期望的错误,但发现了另一个。 在我的课堂上,我已经实现并拥有一个我认为足够的领域。 我是Java序列化的新手。我在这里想念什么? 编辑 如果有关系,我实际上是在尝试读写 这是完整的痕迹: 问题答案: 您正在读取文件吗?在这种情况下,是否立即添加serialVersionUID无关紧要,它不同于文件中存储的那个,并且会创建异常。

  • 我试图使用kafkastreams进行聚合,但得到的错误如下所示 这是我正在做的事情: 我收到的错误如下。 由以下原因引起:A 序列化程序(密钥:类型:a 序列化程序(密钥:类型:网站名称:通用序列化程序 / 值:在流配置中更改默认的 Serdes 或通过方法参数提供正确的 Serdes。在 org.apache.kafka.流.处理器.内部.sinkNode.进程 (SinkNode.java:

  • 序列化和反序列化的方式不同于 我已经创建了两个序列化程序 和 我用Jackson查看了序列化/反序列化映射 ,但找不到解决方案。

  • 问题内容: 我们有一个Hadoop集群,我们在上面存储使用Kryo(序列化框架)序列化为字节的数据。我们用于此目的的Kryo版本是从2.21正式版本派生而来的,以将我们自己的补丁应用于我们使用Kryo遇到的问题。当前的Kryo版本2.22也解决了这些问题,但是具有不同的解决方案。结果,我们不能仅仅更改我们使用的Kryo版本,因为这意味着我们将不再能够读取已经存储在Hadoop集群中的数据。为了解决

  • 问题内容: 我已经奋斗了几个小时,没有取得好结果。我正在尝试使用.NET JSON序列化程序将JSON从UI来回转换为对象。 小数引起了问题,因为我的文化的标准使用“,”作为小数分隔符而不是“。”。我尝试实现自定义转换器,但效果不佳。 我还检查了NewtonSoft JSON.net,但没有得到更好的结果。到目前为止,似乎与值类型的匹配是文化不变的。我要覆盖此行为,该怎么办? 顺便说一句,我真的很