背景
Java Object Serialization 会使用对象中的serialVersionUID
私有静态常量长整型属性(private static final long
)作为该对象的版本号,反序列化时 JVM 会校验该版本号是否和序列化时的一致,如果不一致会导致序列化失败,抛出InvalidClassException
异常。
默认情况下,JVM 为每一个实现了Serializable
的接口的类生成一个serialVersionUID
,这个版本ID的计算规则是通过当前类信息(类名、属性、方法、修饰符等)生成的,所以当属性有变更时这个serialVersionUID
也一定会发生变更(简单新增空行、空格并不会影响serialVersionUID
生成)。
这个serialVersionUID
的生成,和所使用的JDK有关,不同的JDK可能会生成不一样的版本ID。
而且考虑到实际业务场景,变更属性修改类是常有的事,如果使用自动生成的版本ID很容易造成serialVersionUID
不一致的问题,导致反序列化失败。
所以最好是手动显示生成,大多数 JAVA IDE 都会提供自动生成版本ID的功能。
serialVersionUID不一致的兼容处理
普通序列化(Serialization) 和 反序列化(Deserialization):
public class SerializeTest {
public static void main(String[] args) throws Exception {
// Serialize to a file.
FileOutputStream f = new FileOutputStream("./tmp");
ObjectOutput s = new ObjectOutputStream(f);
s.writeObject("Today");
s.writeObject(new Person());
s.flush();