版权声明:本文为博主fbysss原创文章,转载请注明出处

作者:fbysss
msn:jameslastchina@hotmail.com 
blog:blog.csdn.NET/fbysss
声明:本文由fbysss原创,转载请注明出处
关键字:SerialVersionUid 序列化

一、前言

SerialVersionUid,简言之,其目的是序列化对象版本控制,有关各版本反序列化时是否兼容。如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassException异常。如果修改较小,比如仅仅是增加了一个属性,我们希望向下兼容,老版本的数据都能保留,那就不用修改;如果我们删除了一个属性,或者更改了类的继承关系,必然不兼容旧数据,这时就应该手动更新版本号,即SerialVersionUid。

关于其定义,可参考JDK文档:http://download.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html

二、问题

1.如果不显式设置SerialVersionUid,有什么后果?

jdk文档中有解释,建议我们显式声明,因为如果不声明,JVM会为我们自动产生一个值,但这个值和编译器的实现相关,并不稳定,这样就可能在不同JVM环境下出现反序列化时报InvalidClassException异常。

...it is strongly
recommended that all serializable classes explicitly declare
serialVersionUID values, since the default serialVersionUID computation
is highly sensitive to class details that may vary depending on compiler
implementations...

2.两种SerialVersionUid有什么区别?

在Eclipse中,提供两种方式让我们快速添加SerialVersionUid。

add default serial version ID
Adds a default serial version ID to the selected type
Use this option to add a user-defined ID in combination with custom serialization code if the type did undergo structural change since its first release.

add generated serial version ID:
Adds a generated serial version ID to the selected type
Use this option to add a compiler-generated ID if the type didnot undergo structural change since its first release.

一种就是1L,一种是生成一个很大的数,这两种有什么区别呢?

看上去,好像每个类的这个类不同,似乎这个SerialVersionUid在类之间有某种关联。其实不然,两种都可以,从JDK文档也看不出这一点。我们只要保证在同一个类中,不同版本根据兼容需要,是否更改SerialVersionUid即可。

对于第一种,需要了解哪些情况是可兼容的,哪些根本就不兼容。 参考文档:http://Java.sun.com/j2se/1.4/pdf/serial-spec.pdf

在可兼容的前提下,可以保留旧版本号,如果不兼容,或者想让它不兼容,就手工递增版本号。

1->2->3.....

第二种方式,是根据类的结构产生的hash值。增减一个属性、方法等,都可能导致这个值产生变化。我想这种方式适用于这样的场景:

开发者认为每次修改类后就需要生成新的版本号,不想向下兼容,操作就是删除原有serialVesionUid声明语句,再自动生成一下。

个人认为,一般采用第一种就行了,简单。第二种能够保证每次更改类结构后改变版本号,但还是要手工去生成,并不是修改了类,会提示你要去更新这个SerialVersionUid,所以虽然看上去很cool,实际上让人很迷惑。

参考:

1.一篇较好的关于serialVesionUid的说明:

http://www.mkyong.com/java-best-practices/understand-the-serialversionuid/

2.serialVesionUid相关讨论

http://stackoverflow.com/questions/888335/why-generate-long-serialversionuid-instead-of-a-simple-1l

3.compiler-generated ID生成算法

http://java.sun.com/javase/6/docs/platform/serialization/spec/class.html#4100

其他相关问题:

hibernate的持久化,这个一般指的是将数据持久化到数据库,和序列化并没有直接关系。

Hibernate的POJO也并不要求必须实现Serializable接口,但是,作为系统扩展考虑,应该把PO都实现Serializable接口,因为如果这些对象需要缓存到磁盘上,或者在分布式环境下使用,就必须序列化,最常见的例子就是ehcache、Memcached。key和value中的对象都必须是序列化的对象。

Java序列化中的SerialVersionUid的更多相关文章

  1. Java序列化中的serialVersionUID有什么用?

    如果一个实现了Serializable的类没有serialVersionUID属性,IDE(比如Eclipse)通常会报这样一个warning: The serializable class Foo ...

  2. 理解Java序列化中的SerialVersionUid

    一.前言 SerialVersionUid,简言之,其目的是序列化对象版本控制,有关各版本反序列化时是否兼容.如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClass ...

  3. 2017.12.22 Java序列化中你不知道的事(一)

    Java 序列化简介 Java 对象序列化是 JDK 1.1 中引入的一组开创性特性之一,用于作为一种将 Java 对象的状态转换为字节数组,以便存储或传输的机制,以后,仍可以将字节数组转换回 Jav ...

  4. 关于java序列化中的一个细节

    java序列化机制的可以参考很多资料了,最近在看的时候发现了一些问题. 1. 默认的序列化机制,很多书里讲到序列化类只序列化类名,实例变量,不会实例化类变量(static)和瞬态变量(transien ...

  5. 【Java】Java 序列化的高级认识

    如果你只知道实现 Serializable 接口的对象,可以序列化为本地文件.那你最好再阅读该篇文章,文章对序列化进行了更深一步的讨论,用实际的例子代码讲述了序列化的高级认识,包括父类序列化的问题.静 ...

  6. 深入理解JAVA序列化

    如果你只知道实现 Serializable 接口的对象,可以序列化为本地文件.那你最好再阅读该篇文章,文章对序列化进行了更深一步的讨论,用实际的例子代码讲述了序列化的高级认识,包括父类序列化的问题.静 ...

  7. java基础(十)-----Java 序列化的高级认识

    将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口,使用 ...

  8. Java序列化系列教程(下)

    一引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口 ...

  9. 关于Java序列化和Hadoop的序列化

    import java.io.DataInput; import java.io.DataOutput; import java.io.DataOutputStream; import java.io ...

随机推荐

  1. Oracle 常用SQL技巧(转)

    1. SELECT子句中避免使用 “*”当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解 ...

  2. mysql IP转换函数

    1.将字符串类型的实际IP转换成十进制数值型的 SELECT INET_ATON('209.207.224.40'); 执行结果:

  3. C语言(函数)学习之strstr strcasestr

    C语言(函数)学习之[strstr]&[strcasestr]一.strstr函数使用[1]函数原型char*strstr(constchar*haystack,constchar*needl ...

  4. linux面试题

    一.填空题: 1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取uu要加载的文件系统. 3. Linux文件系统中每个文件用 i节点 ...

  5. SVN Unable to connect to a repository at UR

    背景: 1.         SVN服务器:VisualSVN-Server-2.5.5: 2.         SVN客户端:TortoiseSVN-1.7.6.22632-x64-svn-1.7. ...

  6. Codevs 1025 选菜

    题目描述 Description 在小松宿舍楼下的不远处,有PK大学最不错的一个食堂--The Farmer's Canteen(NM食堂).由于该食堂的菜都很不错,价格也公道,所以很多人都喜欢来这边 ...

  7. PHP读取超大文件的实例代码

    数据量大带来的问题就是单个文件很大,能够打开这个文件相当不容易,记事本就不要指望了,果断死机   去年年底的各种网站帐号信息的数据库泄漏,很是给力啊,趁机也下载了几个数据库,准备学学数据分析家来分析一 ...

  8. 洛谷P1141 01迷宫

    题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫, ...

  9. 游戏/APP的多语言系统设计

    多语言需求 游戏或者APP中可以根据不同地区显示不同语言,那么这是怎么实现的呢?要如何处理应用中的图片呢? 思路分析 系统设计 字体翻译显示 多语言收集工具 图例解释 把界面上出现的文字,翻译到多语言 ...

  10. S2结业考试的第一次测验

    错题分析: 1:java中的错误处理是通过异常处理模型来实现的,那么异常处理模块能处理的错误是: A:运行时错误 B:逻辑错误 C:语法错误 D:内部错误 正确答案是:A 解析:运行时异常都是Runt ...