推广 热搜:   公司  快速  企业  中国  设备    上海  行业  未来 

又一个难题!Java序列化和反序列化为什么不能修改 serialVersionUID

   日期:2024-10-31     移动:http://keant.xrbh.cn/quote/9140.html

阿里巴巴开发手册(四)OOP 规约,第 13 条解释如下

又一个难题!Java序列化和反序列化为什么不能修改 serialVersionUID

【强制】序列化类新增属性时,请不要修改 字段,避免反序列失败;如果 完全不兼容升级,避免反序列化混乱,那么请修改 值。说明:注意 不一致会抛出序列化运行时异常。

首先需要解释一下这条规则,并不是要求你一定不可以修改,而是根据自己的需要来修改。我们先了解一下 是干嘛的。

首先我们需要了解一下序列化,我们可以简单了理解序列化就是把 对象转换成另一种的数据,这种的数据可以用于存储或者是传输。因为本身 对象是存在内存中,没有办法直接存储或者是传输,序列化的出现来解决这个问题,那么反序列化就是把数据重新转换为 对象。当然这个可以是多种格式,比如我们详知的 ,或者是 ,也可以是我们的自定义形式,比如 形式,如下图。

说到 就不得不说到 默认的序列化,为了提供上文我们说的存储和传出, 默认提供了一种序列化方式。只要序列化的类实现 接口,这样就可以做序列化和反序列化了。我简单罗列了一下代码这样更直观(有所删减)。

代码已经比较直观, 实现了 接口,通过 把类转化为字节码存入 ,然后再使用 把字节码从   读入内存。这样非常简单就实现了 的序列化,说了这么多它真的有用途吗?当然,比如 自带的远程调用组件 。

终于说到重点了,为什么不能轻易修改 ?可是上面的代码中我们明明就没有设置 。那我们调整一下例子,再测试一次。

如上代码,我们先运行 ,然后修改 ,添加一个属性 ,然后再次运行代码。果然出错了

显示 不相同,反序列化失败了,可是我们没有定义 是为什么呢?(所有源码文末均有获取方式)
是时候让源码君出面了,我们查看 ,如果当前类()没有定义 ,就会调用生成默认的序列化唯一标示。我们简单的看代码,发现他的生成规则是根据类名,结果明,方法和属性等参数生成的 值,所以我们给 添加了 属性,所以对应的 肯定会变化。

JVM 规范[1] 里面也有具体的解释

这里我们也可以使用 自带的工具 来验证一下,这个工具和 默认的生成 的规则一样。

可以得到添加 前后的 ,输出如下

好了,所以看到这里我们修改一个地方就可以解决这个问题了。手工定义一个 代码如下

这样再重复上面的运行步骤,就可以成功的做反序列化了。

到这里我们就全部明白了为什么文档里面说明不能轻易的修改 了。但是每次定义成 1L 也不是办法,所以可以配置一下 ,这样就可以创建类的时候提示自动生成了。

手册里面只提到了 默认的序列化方式,其实还有很多性能很不错的序列化方式,正如上文中提到的 或是字节流,比如现在比较流行的几种:、、、、 等,具体在这里就不展开了,他们都有自己的优缺点,下面是 jvm-serializers[2] 输出的它们的性能比较,可以在选择的时候有限参考下。

链接: https://pan.baidu.com/s/1psiy00_0xeDk6RpsKFFKMA
提取码: vftp
源码:https://github.com/codedrinker/Head-First-Java-Alibaba-Coding-Guidelines

参考资料

[1]

JVM 规范: https://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100

[2]

jvm-serializers: https://github.com/eishay/jvm-serializers/wiki

本文地址:http://lianchengexpo.xrbh.cn/quote/9140.html    迅博思语资讯 http://lianchengexpo.xrbh.cn/ , 查看更多

特别提示:本信息由相关企业自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


相关行业动态
推荐行业动态
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  粤ICP备2023022329号