未显式指定serialVersionUID

当没有显式地定义serialVersionUID变量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本,它通过类名,方法名等诸多因素经过计算而得,和类名、实例方法名、实例属性名等有关,和静态属性名和值、实例属性值无关。

这种情况下,如果class文件(类名,方法名等)没有发生变化(增加空格,换行,增加注释,等等),就算编译再多次,serialVersionUID也不会变化的。但一旦变化,那么在反序列化时就会出现序列化版本不一致的异常InvalidCastException

反序列化过程

  1. 首先,载入需要反序列化的byte[]数组,并解析出类名全路径,jvm会使用URLClassLoader去找本虚拟机中是否加载过这样类名的一个类;

  2. 如果有,计算这个类的serialVersionUID值(如果显示声明了就不用计算,直接用),再和byte[]数组中的serialVersionUID对比,不相同报出异常;

  3. 当相同时,根据刚刚得到的类名全路径newInstance一个对象出来,然后使用反射将byte内容一一复制给该对象,最后返回该对象。