Java 为什么不是';是否自动生成serialVersionUID?

Java 为什么不是';是否自动生成serialVersionUID?,java,serialization,serialversionuid,Java,Serialization,Serialversionuid,为什么不自动生成serialVersionUID?我在一个应用程序服务器上遇到了一个问题,显然是缓存了一个旧类。它是根据类的结构自动生成的。如果结构发生更改,则重新生成id(根据类的哈希值) 因此,您最好定义一个显式的serialVersionUID如果您使用Eclipse作为IDE,您可以右键单击关于缺少serialVersionUID的警告,您将得到两个选项: 1) 定义Eclipse默认值,该值为1L;或 2) 定义随机生成的长值 如果您关心序列化对象的版本控制,那么每次修改类时都需要手动

为什么不自动生成
serialVersionUID
?我在一个应用程序服务器上遇到了一个问题,显然是缓存了一个旧类。

它是根据类的结构自动生成的。如果结构发生更改,则重新生成id(根据类的哈希值)


因此,您最好定义一个显式的
serialVersionUID

如果您使用Eclipse作为IDE,您可以右键单击关于缺少serialVersionUID的警告,您将得到两个选项:

1) 定义Eclipse默认值,该值为1L;或
2) 定义随机生成的长值

如果您关心序列化对象的版本控制,那么每次修改类时都需要手动重新生成一个新值。Serializable接口的Javadoc说明了如果根本不声明serialVersionUID会发生什么:

如果可序列化类没有显式声明serialVersionUID,则序列化运行时将根据该类的各个方面计算该类的默认serialVersionUID值,如Java(TM)对象序列化规范中所述。但是,强烈建议所有可序列化类显式声明serialVersionUID值,因为默认的serialVersionUID计算对类细节高度敏感,这些细节可能因编译器实现而异,因此在反序列化过程中可能会导致意外的InvalidClassException。因此,为了保证不同java编译器实现之间的SerialVersionId值一致,可序列化类必须声明显式的SerialVersionId值

在实践中,我发现,即使您在两台或多台计算机(例如,从Subversion签出)上使用相同的源代码,并且在类中未定义serialVersionUID,在编译代码时,类中编译器生成的值在每台计算机上也是不同的。这可能会在开发过程中导致混乱的错误

如果您确信永远不会出现过时的序列化对象与较新版本的类不同步的情况(或者两个JVM相互发送不同步的序列化对象,可能是通过网络或套接字连接),那么只需为serialVersionUID设置1L值,并永远保持这种状态


serialversionuid不会自动生成,因为它很危险。当设置serialversionuid时,它意味着一个类的两个版本在序列化方面是兼容的

假设您有一个名为Foo的类,它没有serialversionuid(默认值),您将Foo的一个实例序列化为一个文件。稍后,将向Foo类添加一些新成员。如果尝试从文件中反序列化Foo对象,则会出现序列化失败,说明对象不兼容。它们是不兼容的,这是您想要的,也是默认设置。它们不兼容,因为Foo类中的新成员无法从Foo的旧序列化实例初始化

现在,您可能会说,“我不在乎,在我的应用程序中,这些字段未初始化是可以接受的”。如果确实如此,可以将新Foo类的serialversionuid设置为与旧Foo类相同。这将告诉Java对象在序列化性方面是兼容的,并且当您将旧的Foo实例反序列化到新的Foo类中时,Java不会抱怨(但新字段仍然未初始化)

如果您是第一次创建一个新类,并且设置了serialversionuid,您正在输入一个协定。该契约是,“对于具有相同serialversionuid的该类的所有未来版本,我将保证它们在状态和序列化方面兼容”


如果您更改了一个类,并且明确希望不允许反序列化旧版本,则可以将serialversionuid更改为新值。如果试图将旧对象反序列化到新类实例中,这将导致引发异常。

“Random”与“generated”不同。对于相同(或足够相似)的源文件,我非常确定该工具保证为您提供相同的UUID。“您需要在每次修改类时手动重新生成一个新值”。绝对不是。这与您应该做的恰恰相反。@EJP:1L是Eclipse的“默认值”。因此您最好定义一个显式的serialVersionUID。你是对的,但他们最好知道如何管理与类的序列化形式相关的变量,否则这是徒劳的。好的一点,有很多关于这方面的文档(我需要通读)。这很有意义。这是我要考虑的另一个问题。我不确定为什么会将其标记为正确答案,因为serialVersionUID是自动生成的。此外,根据情况,自动生成的ID可能有价值,因为它们确保在修改类时有一个新的编号,而不是有人更改代码然后忘记。但显然,并不是所有的情况下,正如这篇文章正确指出的那样。这是如此简单,但却很少有人理解它(或者可以费心去理解它?)。我猜从你使用的大写锁定的数量来看,你对此也感到沮丧。