基于SerialVersionUID的描述:https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100,似乎必须始终在您创建的任何类中包含SerialVersionUID,以便用于序列化的JVM和用于反序列化的不同JVM不会自动分配自己的SerialVersionUID,它们有可能是由于JVM的不同,彼此不同。这适用于控制我自己的类的反序列化,但是如果我想确保JVM B序列化的标准库中的类可以被JVM B反序列化呢?
Map<Integer, String> myMap = new HashMap<>();
HashMap定义了一个SerialVersionUID。但:
public class NewClass implements Serializable
{
private static final long serialVersionUID = 1L;
private final Map<Integer, String> myMap;
public NewClass()
{
this.myMap = new HashMap<>();
}
}
因为反序列化依赖于具有相同SerialVersionUID的HashMap,这在不同的JVM中可能会有所不同,对吧?可能是的,你是对的。
实际上这已经发生在我们不久前的一些swing
课程(我真的不记得究竟是哪一个),但序列化jdkX
并在jdkX+1
de-serailizng他们(那是很久以前的事,抱歉错过了这些细节)事情开始与InvalidClassException
决裂。我们当时已经支付了支持并且开了一个问题 - 响应是,那些类别改变了以至于无法正确地反序列化它们 - 你被这个版本困住了,或者升级到jdk+1
并使用它。从那以后,我没有发生过这种情况,甚至没有发生过一次。
一般来说,我认为,这也是使序列化变得困难的原因。您必须维护这样一个过程,以便从序列化的角度来看,未来版本中的更改可以与之前的版本相关并兼容。
另一方面,HashMap
有一种非常聪明的方法来序列化它的数据。它序列化(除了其他东西,如load_factor
等)只有它的键和值 - 没有别的。因此,无论实施是否发生变化,都可以进行反序列化。出于这个原因,一些不需要的字段被标记为瞬态,例如:
transient int modCount;
transient Set<Map.Entry<K,V>> entrySet;
这个想法是它应该序列化数据与结构。
例如,如果HashMap
以序列化在jdk-11
中破坏的方式发生变化,这会让很多开发人员生气,我怀疑这将是一条路径(除非确实需要)