java serializable 源码_JavaSe: 不要小看了 Serializable

org.apache.catalina.session.StandardManager.startInternal Exception loading sessions from persistent storage

java.io.InvalidClassException: com.bes.webgate.vo.ActiveTransactionInfoVo; localclass incompatiable: stream classdesc serial versionUID =4916958502461176947, local class serialversionUID = -5826417142685217629at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:1601)

...

at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)

...

at org.apache.catalina.session.StandardManager.load(StandardManager.java:162)

...

从上面异常来看,出现了类不兼容的问题。 到底为什么呢?

我们就来说说Serializable序列化的工作机制:

序列化的时候系统会把当前类的serialVersionUID 写入序列化的文件中(也可能是其他中介),当反序列化的时候系统会去检测文件中的serialVersionUID ,看它是否和当前类的serialVersionUID 一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化,否则就说明当前类和序列化的类相比发生了某些变换,比如成员变量的数量,类型可能发生了改变,这个时候就会抛异常,反序列化失败。

那么serialVersionUID 是如何生成,生成规则是怎么样的呢?

默认情况下,也就是不声明serialVersionUID 属性情况下,系统会按当前类的成员变量计算hash值并赋值给serialVersionUID 。所以,结论就出来了。声明serialVersionUID ,可以很大程度上避免反序列化过程的失败。比如当版本升级后,我们可能删除了某个成员变量,

也可能增加了一些新的成员变量,这个时候我们的反序列化依然能够成功,程序依然能够最大程度地恢复数据,相反,如果不指定serialVersionUID ,程序就会挂掉。

当然我们还要考虑另外一种情况,如果类结构发生了非常规性改变,比如修改了类名,类型等,这个时候尽管serialVersionUID 验证通过了,但是反序列化过程还是会失败,因为类结构有了毁灭性的改变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值