Java序列化,UID没有改变。 我可以在课程中添加新的变量和方法吗?

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

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

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

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

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

哇,很多不好的信息。

Java序列化非常强大。 有一套非常明确的规则来管理具有相同uid和不同数据的对象的向后兼容性。 基本思想是,只要不更改现有成员的类型,就可以维护相同的uid而不会出现数据问题。

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

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

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

这只有在您让Java为您的类生成默认UID时才有意义。 它使用类的实际成员和方法来生成它,从而在更改类结构后使其无效。 如果您为您的class级提供UID,那么这只适用于您需要从文件等反序列化您的类的旧版本。

想要定义几点来突出影响序列化的变化。 您将在下面找到Oracle Java Docs的链接以获取更多详细信息。

不兼容的变化

对类的不兼容更改是那些无法保证互操作性的更改。 进化类时可能发生的不兼容更改是:

  1. 删除字段
  2. 在层次结构中向上或向下移动类
  3. 将非静态字段更改为静态字段或非瞬态字段更改为瞬态
  4. 更改原始字段的声明类型
  5. 更改writeObject或readObject方法,使其不再写入或读取默认字段数据或更改它,以便它尝试写入或在先前版本没有时读取它。
  6. 将类从Serializable更改为Externalizable,反之亦然。
  7. 将类从非枚举类型更改为枚举类型,反之亦然。
  8. 删除Serializable或Externalizable。
  9. 将writeReplace或readResolve方法添加到类中,如果该行为会产生与该类的任何旧版本不兼容的对象。

从上述信息的链接http://docs.oracle.com/javase/7/docs/platform/serialization/spec/version.html#6678