序列化与反序列化中serialVersionUID的作用(通俗易懂)
serialVersionUID:字面意思上是序列化的版本号,这个在刚刚接触java编程时,学序列化大家一般都不会注意到,在你一个类序列化后除非你强制去掉了myeclipse中warning的功能,在你实现序列化的类上会有这个警告,点击会出现增加这个版本号。
说说这个版本号得作用:就是确保了不同版本之间的兼容性,不仅能够向前兼容,还能够向后兼容,即在版本升级时反序列化仍保持对象的唯一性。
它有两种生成方式:
一个是默认的1L,比如:private staticfinal long serialVersionUID = 1L;
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如: privatestatic final long serialVersionUID = xxxxL;
从两个例子上来说明这个序列化号的作用:
这是一个类实现了序列化,但是并没有显式的声明序列号,在这里说明一下,如果没有显式声明序列号,那么在程序编译时会自己生成这个版本序列号,
程序1
public class Animal implements Serializable{
publicString name;
publicString no;
}
通过这个程序来将上面的一个实体存起来:程序2
public static void main(String[] args) throws Exception{
Animal an =new Animal();
FileOutputStream f = newFileOutputStream("foo");
ObjectOutputStream oos = newObjectOutputStream(f);
oos.writeObject(an);
oos.close();
}
通过这个程序读取出刚才存储的类:程序3
public static void main(String[] args) throws Exception{
FileInputStream fis = newFileInputStream("foo");
ObjectInputStream ois = newObjectInputStream(fis);
Animal ani = (Animal)ois.readObject();
ois.close();
fis.close();
}
这种编译是成功的,但是当你在程序1中的类增加一个成员变量的时候,在运行程序3,就会报错:
Exception in thread "main" java.io.InvalidClassException:koal.Animal;……
atjava.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
atjava.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583)
atjava.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
atjava.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
atjava.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
atjava.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
atkoal.SerialVersion.main(SerialVersion.java:22)
这是为什么呢?
因为在你没有显式的声明序列号时,在程序编译时候会自动生成一个序列号,存储在文件中,但是在你更改了实体类的时候又会重新生成一个序列号,在程序运行的时候,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。也就是说,在你读取这个object的时候,他会比较你的现在这个类的序列号和你存储的那个序列号是否相等,如果相等,则说明这是同一个版本,如果不相等则是不同版本,不同版本之间的成员变量是不相同的,所以就会报错,但是当你显式的声明了这个序列号时,不论你如何修改类中的成员变量还是方法,都不会引起版本之间不兼容得问题,这个就加强了你的程序的健壮性。
在很多地方我们都会用到这个序列化,例如在游戏中,游戏升级之后,还要能够让程序成功读取以前的数据,让升级之后的程序还能认识以前的数据文件,即使数据格式不一致,也不会丢失数据。
像一些持久化的配置文件,中途要升级,增加属性,都要使用这个版本序列号,在这里我们是希望程序中只要是实现序列化的类都最好是显式的声明这个序列版本号。
序列化与反序列化中serialVersionUID的作用(通俗易懂)的更多相关文章
- java序列化和反序列化中的serialVersionUID有啥用
1.什么是序列化和反序列化 序列化就是将java对象转成字节序列的过程:反序列化就是将字节序列转成java对象的过程. java中,序列化的目的一种是需要将对象保存到硬盘上,一种是对象需要在网络中传 ...
- java.io.Serializable中serialVersionUID的作用
把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网 ...
- JAVA中序列化和反序列化中的静态成员问题
关于这个标题的内容是面试笔试中比较常见的考题,大家跟随我的博客一起来学习下这个过程. ? ? JAVA中的序列化和反序列化主要用于: (1)将对象或者异常等写入文件,通过文件交互传输信息: (2)将对 ...
- Q:java中serialVersionUID的作用
@转载自:http://www.cnblogs.com/guanghuiqq/archive/2012/07/18/2597036.html 简单来说,Java的序列化机制是通过在运行时判断类的s ...
- Java中的序列化与反序列化
序列化定义 将对象转换为字节流保存起来,并在以后还原这个对象,这种机制叫做对象序列化. 将一个对象保存到永久存储设备上称为持久化. 一个对象要想能够实现序列化,必须实现java.io.Serializ ...
- c# 通过json.net中的JsonConverter进行自定义序列化与反序列化
https://www.cnblogs.com/yijiayi/p/10051284.html 相信大家在工作中会经常遇见对json进行序列化与反序列化吧,但通常的序列化与反序列化中的json结构与c ...
- serialVersionUID的作用以及设置方法(转)
声明:本篇文章是转载的 http://blog.csdn.net/kakaxi_77/article/details/8129070 http://snowlotus.iteye.com/blog/2 ...
- 序列化和反序列化为什么要实现Serializable接口?(史上最全、简单易懂)
目录结 前言 1.什么是序列化和反序列化 2.什么时候需要进行序列化和反序列化 2.1.服务器和浏览器交互时用到了Serializable接口吗? 2.2.Mybatis将数据持久化到数据库中用到了S ...
- Hessian 序列化和反序列化实现
先聊聊 Java的序列化,Java官方的序列化和反序列化的实现被太多人吐槽,这得归于Java官方序列化实现的方式. 1.Java序列化的性能经常被吐槽.2.Java官方的序列化后的数据相对于一些优秀的 ...
随机推荐
- python 函数递归
##recursive递归 递归特性:1. 必须有一个明确的结束条件2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通 ...
- C++笔记002:VS2010报错:LINK fatal error LNK1123 转换到 COFF 期间失败文件无效或损坏
原创笔记,转载请注明出处! 点击[关注],关注也是一种美德~ 错误描述: 1>------ 已启动生成: 项目: FirstCode, 配置: Debug Win32 ------ 1>生 ...
- 一个环形公路,上面有N个站点,A1, ..., AN,其中Ai和Ai+1之间的距离为Di,AN和A1之间的距离为D0。 高效的求第i和第j个站点之间的距离,空间复杂度不超过O(N)。
//点数 #define N 10 //点间距 int D[N]; //A1到每个Ai的距离 int A1ToX[N]; void preprocess() { srand(time(0)); //随 ...
- Python 函数参数传递机制.
learning python,5e中讲到.Python的函数参数传递机制是对象引用. Arguments are passed by assignment (object reference). I ...
- PHP和MySQL Web开发学习笔记介绍
前言 从2016年2月1日开始,之后的几个月左右的时间里,我会写一个系列的PHP和MySQL Web开发的学习笔记.我之前一直从事Java语言的开发工作,最近这段时间非常想学习一门语言,就选择了PHP ...
- Linux 环境下的一些常用命令(三)
转载自 http://www.oschina.net/translate/20-advanced-commands-for-middle-level-linux-users 21. 命令: Find ...
- AP模块NOTE修改API
--创建 AP_NOTES_PUB.Create_Note ( p_api_version IN NUMBER , p_init_msg_list IN VARCHAR2 := FND_API.G_F ...
- FFmpeg源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- 微信小程序的开发:通过微信小程序看前端
前言 2016年9月22日凌晨,微信官方通过"微信公开课"公众号发布了关于微信小程序(微信应用号)的内测通知.整个朋友圈瞬间便像炸开了锅似的,各种揣测.介绍性文章在一夜里诞生.而真 ...
- Cocos2D iOS之旅:如何写一个敲地鼠游戏(六):放置地鼠
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...