简体   繁体   English

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

[英]SerialVersionUID in the Java standard library across different JVMs

Based on the description of SerialVersionUID here: https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100 , it seems necessary to always include SerialVersionUID in any classes you create so that a JVM used for serialization and a different JVM used for deserialzation won't automatically assign their own SerialVersionUIDs, which have potential to be different from one another because of differences in the JVM. 根据此处对SerialVersionUID的描述: https ://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100,似乎有必要始终在您创建的任何类中包括SerialVersionUID,以便用于序列化的JVM和用于反序列化的不同JVM不会自动分配它们自己的SerialVersionUID,由于JVM的不同,它们可能彼此不同。 This works well for controlling deserialzation of my own classes, but what if I want to ensure that classes in the standard library serialized with JVM A can be deserialized by JVM B? 这对于控制我自己的类的反序列化效果很好,但是如果我要确保用JVM B序列化的标准库中的类可以被JVM B反序列化,那该怎么办?

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

HashMap defines a SerialVersionUID. HashMap定义了SerialVersionUID。 But: 但:

  • Since HashMap lives in the java standard library, am I provided any sort of guarantee that if I serialize this HashMap with JVM A that JVM B will be able to deserialize it? 由于HashMap驻留在Java标准库中,因此我是否提供任何保证,如果我使用JVM A序列化此HashMap,则JVM B可以反序列化它? Namely, is JVM B allowed to specify a different SerialVersionUID than JVM A, at least if B is just a minor version upgrade from A? 即,至少如果B只是从A的次要版本升级,是否允许JVM B指定与JVM A不同的SerialVersionUID?
  • If it's not guaranteed for standard library classes, does using SerialVersionUID only really ensure proper deserialization for your own classes that never touch the java standard library? 如果不能保证标准库类,使用SerialVersionUID是否真的可以确保从未接触过Java标准库的自己的类正确地反序列化? For example, a class that looks like this: 例如,一个看起来像这样的类:

     public class NewClass implements Serializable { private static final long serialVersionUID = 1L; private final Map<Integer, String> myMap; public NewClass() { this.myMap = new HashMap<>(); } } 

    would be prone to failure because deserialization depends on HashMap having the same SerialVersionUID, which could be different in different JVMs, right? 容易失败,因为反序列化取决于HashMap具有相同的SerialVersionUID,在不同的JVM中可能不同,对吗?

Potentially yes, you are correct. 可能是的,您是正确的。

Actually this has happened to us a while ago with some swing classes (I really can't remember which exactly), but serializing on jdkX and de-serailizng them on jdkX+1 (that was a really long time ago, sorry for missing these details), things started to break with InvalidClassException . 实际上,这在我们之前发生过,有些swing类(我真的不记得是哪一个),但是在jdkX序列化并在jdkX+1jdkX+1序列化它们(那是很久以前的事情了,很抱歉错过了这些详细信息),事情开始因InvalidClassException而中断。 We had paid support at the time and opened an issue - the response was, well, that those class(es) changed in such a way that it would be impossible to deserialize them back properly - you are stuck with this version, or upgrade to jdk+1 and use that. 当时我们已经提供了支持,并提出了一个问题-答复是,这些类已经以某种方式更改,以致无法正确地反序列化它们-您受此版本困扰,或升级到jdk+1并使用它。 It has not happened to me since then, not even once. 从那以后我就没有发生过,甚至没有一次。

Generally, I think, this is what makes serialization hard too. 通常,我认为,这也是使序列化变得困难的原因。 You have to maintain such a process, so that changes in the future versions can be made relevant and compatible with previous ones, from a serialization point of view. 您必须维护这样一个过程,以便从序列化的角度使将来版本中的更改变得相关并与以前的版本兼容。

On the other note, HashMap has a very smart way to serialize it's data. 另一方面, HashMap具有一种非常智能的方式来序列化其数据。 It serializes (among other things likes load_factor , etc) only it's keys and values - nothing else. 它系列化(尤其喜欢load_factor等), 只是它的键和值-没有别的。 So no matter if the implementation changes, they will be possible to be de-serialzied. 因此,无论实现如何更改,都可以将它们反序列化。 For this reason, some of the fields that would not be needed are marked as transient, for example: 因此,某些不需要的字段被标记为瞬态,例如:

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

The idea is that it should serialize data vs structure. 这个想法是它应该序列化数据与结构。


If HashMap changes in such a way that Serialization would break in jdk-11 for example, this would make a lot of developers angry, I doubt this would ever be a path taken (unless really needed) 如果HashMap发生变化,例如序列化将在jdk-11中断,这将使很多开发人员感到愤怒,我怀疑这是否会是一条路(除非确实需要)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM