跨不同 JVM 的 Java 标准库中的 SerialVersionUID

SerialVersionUID in the Java standard library across different JVMs

根据此处对 SerialVersionUID 的描述:https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100,似乎有必要在您创建的任何 classes 中始终包含 SerialVersionUID,以便用于序列化的 JVM 和用于反序列化的不同 JVM不会自动分配它们自己的 SerialVersionUID,由于 JVM 的差异,它们可能彼此不同。这对于控制我自己的 classes 的反序列化非常有效,但是如果我想确保标准库中用 JVM A 序列化的 classes 可以被 JVM B 反序列化怎么办?

Map<Integer, String> myMap = new HashMap<>();

HashMap 定义了一个 SerialVersionUID。但是:

可能是的,你是对的。

实际上这在我们身上发生过一段时间 swing classes(我真的不记得具体是哪个),但是在 jdkX 和 [=41] 上连载=] 他们在 jdkX+1 上(那是很久以前的事了,很抱歉错过了这些细节),事情开始与 InvalidClassException 分道扬镳。我们当时支付了支持并提出了一个问题 - 回应是,嗯,那些 class(es) 以这样一种方式改变了,以至于不可能正确地反序列化它们 - 你被这个版本所困,或升级到 jdk+1 并使用它。从那以后,我再也没有发生过,一次也没有。

总的来说,我认为这也是使序列化变得困难的原因。你必须维护这样一个过程,以便从序列化的角度来看,未来版本的更改可以与以前的版本相关并兼容。

另一方面,HashMap 有一种非常聪明的方法来序列化它的数据。它序列化(除其他外,如 load_factor 等) 它是键和值 - 没有别的。所以无论实现是否改变,它们都可能是 de-serialzied。出于这个原因,一些不需要的字段被标记为临时的,例如:

 transient int modCount;
 transient Set<Map.Entry<K,V>> entrySet;

想法是它应该序列化数据与结构。


例如,如果 HashMap 以序列化中断 jdk-11 的方式进行更改,这会让很多开发人员生气,我怀疑这是否会被采用(除非 真的需要)