`
lokki
  • 浏览: 59942 次
  • 来自: ...
社区版块
存档分类
最新评论

Serializable、serialVersionUID和serialver

    博客分类:
  • java
阅读更多
以前创建的,也有公布过给几千人,先发上来,有空再整理格式

'''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界面生成的,是一样的。
分享到:
评论
2 楼 tuspark 2015-07-12  
这篇《serialversionuId作用》解释的更清楚,更有通俗易懂。
1 楼 tuspark 2015-07-12  
这篇[url= http://swiftlet.net/archives/1268]《serialversionuId作用》[/url]解释的更清楚,更有通俗易懂。

相关推荐

    Java中serialVersionUID的解释

    Java 中 serialVersionUID 的解释 Java 中的 serialVersionUID 是一个非常重要的概念,在实现 Serializable 接口的类中,它...所以,在实现 Serializable 接口时,我们一定要注意到 serialVersionUID 的定义和使用。

    详述IntelliJ IDEA 中自动生成 serialVersionUID 的方法(图文)

    IntelliJ IDEA 自动生成 serialVersionUID 在 Java 序列化机制中,...IntelliJ IDEA 自动生成 serialVersionUID 是一个非常有用的功能,它可以帮助开发者更方便地实现序列化和反序列化,提高开发效率和质量。

    序列化 serializable demo

    例如,`MySerializable.java`和`Product.java`两个文件可能分别代表实现了`Serializable`接口的类。`MySerializable`可能是自定义的一个示例类,而`Product`可能是表示产品的类,它们都包含了可序列化的属性。 在`...

    可序列化接口Serializable

    `Serializable`接口在Java中扮演着至关重要的角色,它提供了对象持久化和网络传输的能力。理解并熟练掌握序列化机制,可以帮助开发者在实际项目中解决各种问题,提升代码的可维护性和安全性。通过阅读《Java_序列化...

    Intent传递对象Serializable

    1. 实现Serializable虽然方便,但序列化和反序列化过程会消耗一定的性能和内存,特别是对于大型对象,可能会导致内存溢出问题。 2. 序列化后的对象会保存一些元数据,如类名和字段名,如果类结构改变,可能导致反...

    java类中serialVersionUID详解.pdf

    综上所述,`serialVersionUID` 在 Java 的序列化机制中扮演着关键角色,它不仅能够确保序列化数据的一致性和完整性,还能够在类结构发生变化时帮助开发者有效管理版本兼容性问题。理解并正确使用 `serialVersionUID`...

    coreJava: serialVersionUID

    在Java编程中,`serialVersionUID` 是一个非常重要的概念,特别是在序列化和反序列化过程中。这个特殊标识符主要用于版本控制,确保不同版本的类在序列化和反序列化时能够正确匹配。当我们讨论`serialVersionUID`时...

    Serializable java序列号

    如果我们手动指定`serialVersionUID`,就能确保在类结构变化时,序列化和反序列化之间的兼容性。如果不指定,Java会自动生成一个,但这种做法并不总是可靠。 总之,Java序列化是Java开发中的一个重要概念,它提供了...

    Java对象Serializable接口实现详解

    Java对象Serializable接口实现详解 Java中的Serializable接口是java.io包中定义的,...Serializable接口是Java中一个非常重要的接口,它使得Java对象可以被序列化和反序列化,从而实现了对象的持久化存储和网络传输。

    java序列化(Serializable)的作用和反序列化

    private static final long serialVersionUID = 1L; private int width; private int height; private String name; public static void main(String[] args) { try { Box myBox = new Box(); myBox....

    轉Serializable至Stream

    总的来说,将`Serializable`对象转化为`Stream`涉及对象的序列化和流的使用,这对于在网络上传输对象或者在服务器端与客户端之间共享数据是非常有用的。注意,序列化和反序列化可能会涉及安全风险,比如序列化攻击,...

    Android序列化——Serializable与Parcelable

    本文将深入探讨两种主要的序列化方式:Serializable和Parcelable,并比较它们的优缺点以及适用场景。 首先,我们来了解什么是序列化。序列化是将对象的状态转换为可存储或可传输的形式的过程。在Android中,这个...

    java序列化(Serializable)的作用和反序列化.doc

    private static final long serialVersionUID = 1L; private int width; private int height; private String name; public void setWidth(int width) { this.width = width; } public void setHeight(int...

    java.io.Serializable序列化问题

    ### Java.io.Serializable 序列化...通过实现 `Serializable` 接口或 `Externalizable` 接口,可以轻松地实现序列化和反序列化功能。需要注意的是,在实际应用中还需要考虑序列化的效率、安全性以及版本兼容性等问题。

    Serializable在C#中的作用.NET 中的对象序列化

    ### C#中Serializable的作用与对象序列化详解 #### 一、引言 在现代软件开发中,特别是基于.NET框架的应用程序开发中,对象序列化是一项非常重要的技术。它允许将对象的状态转换为一种持久的形式(如文件或网络传输...

    bundle传递基本数据,Parcelable类型数据,Serializable类型数据

    3. 对于Serializable,`putSerializable()`和`getSerializable()`可以处理任何实现了Serializable接口的对象,包括ArrayList或其他集合类。 4. 不同的数据类型必须使用对应的方法进行传递,不能混淆使用。 5. 传递后...

    析Android中的Serializable序列化.rar_Serializable _android

    当一个类实现Serializable接口后,Java运行时系统会自动调用`writeObject()`和`readObject()`方法来完成序列化和反序列化。默认情况下,这些方法会递归地序列化类的所有字段,包括私有和静态字段。但也可以自定义...

    Laravel开发-serializable-values

    在Laravel框架中,"serializable-values"是一个关键概念,它涉及到对象的序列化与反序列化,这对于数据存储和传输至关重要。在这个话题下,我们将深入探讨Laravel如何处理可序列化的值,以及如何利用Luminark提供的...

    Java_Serializable(序列化)的理解和总结

    ### Java Serializable(序列化)的理解和总结 #### 一、序列化的定义与目的 序列化是一种将对象的状态转换为可以存储或传输的形式的过程。在Java中,如果一个类实现了`Serializable`接口,那么该类的对象就可以被...

    Serializable-master.zip

    《深入理解Java序列化:serialVersionUID与序列化过程解析》 在Java编程中,序列化是一种将对象的状态转换为...通过理解`serialVersionUID`和序列化机制,我们可以更好地利用这一功能,提升程序的可维护性和健壮性。

Global site tag (gtag.js) - Google Analytics