Java 序列化,UID 未更改。我可以向类中添加新的变量和方法吗?

2022-09-01 21:38:30

我有一个序列化的类。现在,我需要使用 setter 和 getter 方法向类中添加一个新变量。此类在 RMI 中通过网络发送。

在不更改 UID 的情况下,是否可以为其添加新参数以及 getter 和 setter 方法?我试图编写一个通过网络发送的示例类,并且没有更改UID,并为其添加了新参数以及getter和setter方法。另一方面,我测试了它,我仍然正确地得到了值。我假设,如果我添加新参数,getter和setter方法,我需要更改UID。我错了吗?


答案 1

如果你对一个类的SerialVersionUID进行硬编码(通常为1L),存储一些实例,然后重新定义类,你基本上会得到这样的行为(这或多或少是常识):

  1. 新字段(存在于类定义中,不存在于序列化实例中)被分配一个默认值,该默认值对于对象为 null,或者与基元的未初始化字段的值相同。
  2. 删除的字段(不存在于类定义中,但存在于序列化实例中)将被忽略。

因此,一般的经验法则是,如果您只是添加字段和方法,并且不更改任何现有内容,并且如果您对这些新字段的默认值感到满意,那么您通常没问题。


答案 2

哇,很多不好的信息。

Java序列化是+非常+健壮的。有一组定义得很好的规则来管理具有相同uid和不同数据的对象的向后兼容性。基本思想是,只要您不更改现有成员的类型,就可以保持相同的uid而不会出现数据问题。

也就是说,您的代码仍然需要明智地处理可能丢失数据的类。对象可以正确地反序列化,但某些字段中可能没有数据(例如,如果您向类添加了一个字段,并且正在反序列化该类的旧版本)。如果你的代码可以处理这个问题,那么你可能会保留当前的uid。如果没有,那么你应该改变它。

除了预定义的规则之外,还有一些高级使用方案,您甚至可以更改现有字段的类型,并且仍然设法反序列化数据,但通常只有在极端情况下才需要这样做。

java序列化在网上有很好的文档记录,你应该能够在相关的sun/oracle教程/文档中找到所有这些信息。