Java 为什么依赖ObjectStreamClass.getSerialVersionUID不安全?

Java 为什么依赖ObjectStreamClass.getSerialVersionUID不安全?,java,reflection,serialversionuid,Java,Reflection,Serialversionuid,java规范说:“强烈建议所有可序列化类显式声明serialVersionUID值,因为默认的serialVersionUID计算对类细节高度敏感,这些细节可能因编译器实现而异。” 有人能深入调查一下吗?getSerialVersionUID()方法进行反射,反射在任何地方都被广泛使用,那么什么是编译器相关的呢?关于这个问题的精辟解释在J.Bloch的书《有效的Java》中给出: “第74项:明智地实现可序列化”: 如果未通过声明静态 最后一个名为serialVersionUID的长字段,系统自

java规范说:“强烈建议所有可序列化类显式声明serialVersionUID值,因为默认的serialVersionUID计算对类细节高度敏感,这些细节可能因编译器实现而异。”


有人能深入调查一下吗?getSerialVersionUID()方法进行反射,反射在任何地方都被广泛使用,那么什么是编译器相关的呢?

关于这个问题的精辟解释在J.Bloch的书《有效的Java》中给出:

“第74项:明智地实现可序列化”:

如果未通过声明静态 最后一个名为serialVersionUID的长字段,系统自动 通过对类应用复杂过程在运行时生成它。 自动生成的值受类的名称影响 它实现的接口的名称及其所有公共和 受保护的成员。如果你以任何方式改变了这些东西 例如,通过添加一个简单方便的方法 生成的串行版本UID更改


UPD:我在评论中也被问到,为什么它依赖于编译器。实际上,这里的编译器依赖关系并不是关于
getSerialVersionUID()
算法本身(当然,方法是在运行时调用的),而是关于类本身的描述。例如,可以在编译时将一些合成方法添加到类中,这些方法也将在SUID中计算。有关详细信息,请查看方法
ObjectStreamClass.ComputedDefaultSuid()
,它的作用以及如何计算默认SUID。

,但此解释没有说明编译器依赖于什么。getSerialVersionUID()是否用于实时计算值?@ejaenv,看看我的updEven,没有编译器依赖项,当您更改
静态
字段或方法时,您不想使用认为持久形式不兼容的算法。即使类是否具有初始值设定项也会产生影响。引用文本没有提到的是,不仅“它的所有公共和受保护的成员”,而且所有包私有成员都被计算在内,这就是为什么像内部类访问器这样的合成方法很重要……IMO ComputedDefaultSuid应该被更改为一个有用的方法。@ejaenv:嗯,更改算法将破坏与所有现有序列化数据的兼容性,还意味着使用新算法存储的数据将被旧的JRE拒绝。