以前创建的,也有公布过给几千人,先发上来,有空再整理格式
'''Serializable、serialVersionUID和serialver'''
= 一些要求 =
(1)通过网络传输的对象,必须实现Serializable接口,或者父类已经实现序列化接口。
(2)网络传输对象封装太多层次的父类不太好,或者说在interface上用父类定义,然后将子类实例传递给网络另一端的应用可能没这个jar包/class,反序列化不了的。另一可能情况,动态代理接口InvocationHandler invoke(Object proxy, Method method, Object[] args),传进时,method的参数定义匹配interface上的method参数定义,比如是父类,从args获取的class是子类,如果某种rpc技术处理不当(HSF还算可用),或无从识别,困扰的是使用者。
(3)网络接口上的参数、返回值类型、会抛出的异常类,都要实现序列化接口。包括层层里面装着的内容,父类(比较少人对这field推敲private/protected,父类可能有直接被使用的时候)。
(4)ArrayList.subList()返回的List实现类是内部类型,不能序列化的,通过网络传输会出错。
(5)<font color="#ff0000">网络对象第一次上线使用时,就要设定serialVersionUID,不要不顾编译警告</font>
网络对象的匹配,除了靠类名,还靠serialVersionUID,serialVersionUID在《Java语言规范》有固定算法,跟各field的定义相关,如果没有显式赋值,虽然看不见,但会底下会默认算出一个进行网络传输。
如果没有显式赋值,也在你看不见觉察不到的情况下,在你增减了field/修改了定义的情况下,serialVersionUID已被改变,这时网络两端就对接不上而悲剧了。没定义serialVersionUID,而又发生了serialVersionUID变化,网络两端只有所有机器都停掉,并且先后起有顺序时,才能不出丝毫差错。
(6)网络传输对象要有无参构造器,因为机器系统是不知道传什么内容给有参构造器进行实例化,无参构造器不是public都没关系。没定义无参构造器,有些序列化方式会在底下生成无参构造器的方式才能解决问题。
(7)网络传输最好不要用enum类型,太强耦合,从网络一端传到另一端,对方可能还是旧版本而识别不了。[http://hi.baidu.com/yl_ty/blog/item/3a7f350b5710191495ca6bd2.html 别人文章里有enum的序列化说明]
[http://www.cnblogs.com/diyunpeng/archive/2011/03/17/1987121.html 以及这篇的末尾]
(8)有的人喜欢用1L作为serialVersionUID,但不知道是否是通配值,一开始就有赋值肯定没错,0L对于java enum的序列化有特殊意义。
(9)看看HashMap、Date的源代码,不需通过网络传输的field用transient定义,然后实现writeObject等方法。不是所有场合都识别Externalizable,或许都要此场合特别支持Externalizable才行。
(10)有些系列化格式,遇到反序列化不了的类,会反序列化成Map,但会在使用时遇到class cast异常。
(11)不用抛客户端没有jar的异常类到客户端
(12)同一应用不要有同package同名类,即使隐藏在同名/不同名/不同版本的jar中。
(13)远程调用、notify、放入tair、本地保存,或许都需要经过序列化,虽然让你透明地使用网络/感觉不到。
(14)不要序列化大数据对象/十分复杂对象,一般long/int/String/Map/List/Array等常见类组成的对象就已能解决问题,最好不要在本应用的业务接口传递/返回另一人主导业务/结构的对象。
不是建议不要用ArrayList,只是要注意ArrayList经过网络后可能顺序不一样。两需一一对应的List,经过网络后不一定一一对应。List中有零星的null,可能会给别人造成麻烦。
= 先前没设定serialVersionUID,怎么办 =
由于没赋值serialVersionUID 只是警告,不是错误,造成先前没留意设定serialVersionUID,<font color="#ff0000">网络两端上线运行一段时间也感觉正常</font>。
如果再增减修改field,没赋值好serialVersionUID,网络两端就不匹配。
解决步骤如下:serialver命令在jdk/bin目录,用于算出某类的serialVersionUID。
(1)用旧代码的类生成 serialVersionUID:
serialver -classpath myjar-1.0.jar com.taobao.myjar.MyDO
输出结果类似:com.taobao.myjar.MyDO: static final long serialVersionUID = 2075130392266935898L;
(2)然后将这行代码复制到新代码上。
即是说,
如果要在序列化DO里增加/变化field,又要和旧的没有serialVersionUID的DO作兼容,可以用serialver算出旧DO的serialVersionUID,赋值给变化了的DO,这样两边就匹配了
其它说明:
(3)可能会造成两边不匹配的改动,最好是搭车在两端都停机发布时。如果按以上方法做,应该不需出现如此情形。
(4)如果其它field不变动时,增加由serialver自动生成serialVersionUID并不会造成不匹配的情况。
(5)相同的代码,用serialver生成的和用eclipse界面生成的,是一样的。
分享到:
相关推荐
Java_Serializable(序列化) 的理解和总结
序列化 serializable demo ! 序列化 serializable demo !
說明如何將Serializable物件轉成stream
java->serializable深入了解 java->serializable深入了解 java->serializable深入了解
java序列化(Serializable)的作用和反序列化.doc 有详细的讲解哦。 在什么地方用的到都有说明的.
Serializable的增删改查操作,已经经过验证,可以直接运行。
Laravel开发-serializable-values Luminark可序列化值包。
Intent传递数据是android开发中最长用的数据传递方式,可是要传递对象不怎么常用,这里介绍第一种传递对象的方法Serializable传递
详细讲解了C#中关于对象序列化的知识,包括基本序列化、选择序列化、自定义序列化;对于了解在C#中如何进行对象的序列化有价值
java.io.Serializable序列化问题
bundle传递基本数据,Parcelable类型数据,Serializable类型数据
Android序列化——Serializable与Parcelable
java 序列化 对象 Serializable 写着玩的Demo 简单 实用
面试官:“说一下Serializable接口和Parcelable接口的区别吧。” 我们可以从以下两方面来说一说~ 首先我们先给两者来个简单的介绍: 1.定义 Serializable(Java自带): Serializable是序列化的意思,表示将一个对象...
Android中的Serializable
[Serializable]在C_中的作用-NET_中的对象序列化,希望有所帮助
java 将对象序列化 输出对象的值,不懂可以百度序列化干啥的,为什么要用序列化,好处。
序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保 存object states,但是Java给你提供一...
NULL 博文链接:https://tony-lee-s.iteye.com/blog/1416044
java序列化(Serializable)的作用和反序列化.pdf