关于serialVersionUID与序列化"
java序列化trick and trap
厂内经常出现序列化对象版本不匹配问题,于是发本文说明一些序列化的注意点
调用MQ、memcached、rpc等等涉及到远程通讯的都会经过序列化,虽然客户端透明的封装了细节,但底层是一定会有序列化操作的。因此了解序列化的注意事项是非常有必要的,可以避免误用导致潜在的风险
通过网络传输的对象,必须实现Serializable接口,或者父类已经实现序列化接口。
网络传输对象继承层次不宜过深,封装在内部的对象也不宜太复杂。(太复杂很容易出现某个相关的类没实现序列化接口,而导致整个对象无法序列化)
- 一般long/int/String/Map/List/Array等常见类组成的对象就 能解决问题
- 最好不要在本应用对外的业务接口中传递或返回“由另一人或系统主导的业务对象"。因为你不能保证别人的对象版本会兼容,从而导致错误扩散
在接口定义上用的是父类,实际远程传输过去的是子类,反序列化不了的。特别是在rpc中客户端容易出现此问题
远程接口上的参数、返回值类型、会抛出的异常类,都要实现序列化接口。并且server和client都要有对应的类。
- 一个比较容易忽略的例子是:某服务接口可能会抛出某个运行时异常,但没有把这个异常类放入客户端中,一旦抛出此异常,客户端接收到此异常就会无法反序列化
ArrayList.subList()返回的List实现类是内部类型,不能序列化的,通过网络传输会出错。
ArrayList经过网络传输后,里面的元素顺序可能不一样
网络传输对象要有无参构造器(如果定义了有参构造器那就要显式定义一个无参构造起),因为机器是不知道传什么内容给有参构造器进行实例化,无参构造器不是public都没关系。没定义无参构造器,有些序列化方式会在底下生成无参构造器的方式才能解决问题。
网络传输最好不要用enum类型,太强耦合,从网络一端传到另一端,对方可能还是旧版本而识别不了。
- Enum 常量的序列化不同于普通的 serializable 或 externalizable 对象。enum 常量的序列化形式只包含其名称;常量的字段值不被传送。为了序列化 enum 常量,ObjectOutputStream 需要写入由常量的名称方法返回的字符串。
不需通过网络传输的field用transient定义,但有些json序列化类库是不会区别对待这种field
有些序列化类库,遇到反序列化不了的类,会反序列化成Map,但会在使用时遇到class cast异常。
同一应用不要有同package同名的类,可能隐藏在同名/不同名/不同版本的jar中。
serialVersionUID
用于网络传输的对象,第一次上线使用时,就一定要设定serialVersionUID,不要不顾编译警告
NOTE: 网络对象的匹配,除了靠类名,还靠serialVersionUID,serialVersionUID在《Java语言规范》有固定算法,跟各field的定义相关,如果没有显式赋值,虽然看不见,但会底下会默认算出一个进行网络传输。
如果没有显式赋值,在看不见觉察不到的情况下,在你增减了field/修改了定义的情况下,serialVersionUID已被改变,这时网络两端就对接不上而悲剧了。
没定义serialVersionUID,而又发生了serialVersionUID变化,网络两端只有所有机器都停掉,并且先后起有顺序时,才能不出丝毫差错。
最好不要用用1L作为serialVersionUID。0L对于java enum的序列化有特殊意义。
没赋值serialVersionUID 只是警告,不是错误,造成没设定serialVersionUID,网络两端上线运行一段时间也感觉正常。如果再增减修改field,没赋值好serialVersionUID,网络两端就不匹配。
- 算出旧版本的serialVersionUID(使用serialver或eclipse),设置到新版本的代码中
本文大部分内容取自前同事的分享资料,作了少许修改,外网地址
更多精彩内容请访问首发博客http://jenwang.me
进一步交流:
- Email:jenwang@foxmail.com
- 对于本博客某些话题感兴趣,希望进一步交流的,请加 qq 群:2825967
- 更多技术交流分享在圈子「架构杂谈」,跟老司机们聊聊互联网前沿技术、架构、工具、解决方案等
关于serialVersionUID与序列化"的更多相关文章
- java 序列化 serialVersionUID 的作用 和 两种添加方式
serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...
- Java 基础 - java序列化 & serialVersionUID
ref: https://www.cnblogs.com/duanxz/p/3511695.html ------------------- SerialVersionUID概述 SerialVers ...
- 一文看懂Java序列化之serialVersionUID
serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...
- serialVersionUID序列化版本号与ObjectOutputStream对象输入输出流
1. 观察ObjectOutputStream 我们观察ObjectOutputStream就可以发现该类没有无参构造,只有有参构造,所以他是一个包装流 2. 具体使用: public static ...
- 序列化之serialVersionUID
serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性. 序列化ID起着关键的作用,java的序列化机制是通过在运行时判断类的serialVer ...
- Java中的序列化Serialable高级详解
来自[http://blog.csdn.net/jiangwei0910410003/article/details/18989711] 引言 将 Java 对象序列化为二进制文件的 Java 序列化 ...
- Java的序列化ID的作用
Java的序列化ID的作用 简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的serialVersio ...
- 黑马程序员_Java基础:序列化(Serializable)与反序列化
------- android培训.java培训.期待与您交流! ---------- 在学习IO中的ObjectOutputStream和ObjectInputStream时,会涉及到序列化和反序列 ...
- Java序列化的几种方式以及序列化的作用
Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用 有的时候我们想要把一个Java对象 ...
随机推荐
- Mac下利用SSH进行传输文件(转)
//1.从服务器上下载文件 scp username@servername:/path/filename /var/www/local_dir(本地目录) //例如scp root@192.168.0 ...
- (转)C# 正则表达式
最近写爬虫时需要用到正则表达式,有段时间没有使用正则表达式现在渐渐感觉有些淡忘,现在使用还需要去查询一些资料.为了避免以后这样的情况,在此记录下正则表达式的一些基本使用方法附带小的实例.让以后在使用时 ...
- PHP在 win7 64位 旗舰版 报错 Call to undefined function curl_init()
代码在ubuntu下无缝运行OK 转到我的win7 64位 期间 学习机上 报错: Call to undefined function curl_init() 因为用到curl 远程抓取数据. 所以 ...
- Hive 外部表新增字段或者修改字段类型等不生效
标题比较笼统,实际情况是: 对于Hive 的分区外部表的已有分区,在对表新增或者修改字段后,相关分区不生效. 原因是:表元数据虽然修改成功,但是分区也会对应列的元数据,这个地方不会随表的元数据修改而修 ...
- 【开源组件】FastDFS极速入门与安装
FastDFS是一个开源的轻量级的分布式文件系统,为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供 ...
- bash切割文件
split -l 100 ./x01.txt -d -a 3 --additional-suffix=.txt 将 x01.txt文件,-l 100 按照每个100行, -d 以数字累加, -a 3 ...
- NetXray
NetXRay是由Cinco Networks公司开发的一个用于高级分组检错的软件,功能很强大.IP地址查询工具. 硬件要求 对硬件要求低,可运行常用的windows平台. 主要功能 1.监视网络状态 ...
- vs2015中的数据库架构对比工具(New Schema Comparison)
大家都知道VS里的功能多到你根本没用过,今天来说说这个New Schema Comparison,他能做的事情就是在vs中对比我们两个数据库的架构.结构,并且能够更新过去或者生成脚本. Step.1( ...
- Vue 多路由文件的合并
Vue 多路由文件的合并 1.使用的是ES6 数组的合并方法 let routes = new Set([...routes1, ...homerouters]);2.两个路由文件,导出的实际上就是一 ...
- 安装vmware player
一.简介 什么是虚拟机? 虚拟机是通过软件来模拟一个完整的计算机系统.简单来说,你可以在当前系统中通过虚拟机软件运行另外一个系统,并且与当前系统隔离. 什么是vmware? vmware(virtua ...