java中序列化的serialVersionUID解释
serialVersionUID: 字面意思上是序列化的版本号,这个在刚刚接触java编程时,学序列化大家一般都不会注意到,在你一个类序列化后除非你强制去掉了myeclipse中warning的功能,在你实现序列化的类上会有这个警告,点击会出现增加这个版本号。
说说这个版本号得作用: 就是确保了不同版本之间的兼容性,不仅能够向前兼容,还能够向后兼容,即在版本升级时反序列化仍保持对象的唯一性。
它有两种生成方式:
一个是默认的1L,比如:private static final long serialVersionUID = 1L;
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如: private static final long serialVersionUID = xxxxL;
从两个例子上来说明这个序列化号的作用:
这是一个类实现了序列化,但是并没有显式的声明序列号,在这里说明一下,如果没有显式声明序列号,那么在程序编译时会自己生成这个版本序列号,
程序1
public class Animal implements Serializable{
public String name;
public String no;
}
通过这个程序来将上面的一个实体存起来:程序2
public static void main(String[] args) throws Exception{
Animal an = new Animal();
FileOutputStream f = new FileOutputStream("foo");
ObjectOutputStream oos = new ObjectOutputStream(f);
oos.writeObject(an);
oos.close();
}
通过这个程序读取出刚才存储的类:程序3
public static void main(String[] args) throws Exception{
FileInputStream fis = new FileInputStream("foo");
ObjectInputStream ois = new ObjectInputStream(fis);
Animal ani = (Animal)ois.readObject();
ois.close();
fis.close();
}
这种编译是成功的,但是当你在程序1中的类增加一个成员变量的时候,在运行程序3,就会报错:
Exception in thread "main" java.io.InvalidClassException: koal.Animal;……
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at koal.SerialVersion.main(SerialVersion.java:22)
这是为什么呢?
因为在你没有显式的声明序列号时,在程序编译时候会自动生成一个序列号,存储在文件中,但是在你更改了实体类的时候又会重新生成一个序列号,在程序运行的时候,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。也就是说,在你读取这个object的时候,他会比较你的现在这个类的序列号和你存储的那个序列号是否相等,如果相等,则说明这是同一个版本,如果不相等则是不同版本,不同版本之间的成员变量是不相同的,所以就会报错,但是当你显式的声明了这个序列号时,不论你如何修改类中的成员变量还是方法,都不会引起版本之间不兼容得问题,这个就加强了你的程序的健壮性。
在很多地方我们都会用到这个序列化,例如在游戏中,游戏升级之后,还要能够让程序成功读取以前的数据,让升级之后的程序还能认识以前的数据文件,即使数据格式不一致,也不会丢失数据。
像一些持久化的配置文件,中途要升级,增加属性,都要使用这个版本序列号,在这里我们是希望程序中只要是实现序列化的类都最好是显式的声明这个序列版本号。
java中序列化的serialVersionUID解释相关推荐
- java中序列化与反序列化_Java中的序列化
java中序列化与反序列化 Java提供了一种称为序列化的机制,以按字节的有序或字节序列的形式持久化Java对象,其中包括对象的数据以及有关对象的类型和存储在对象中的数据类型的信息. 因此,如果我们已 ...
- java中序列化之子类继承父类序列化
原文 父类实现了Serializable,子类不需要实现Serializable 相关注意事项 a)序列化时,只对对象的状态进行保存,而不管对象的方法: b)当一个父类实现序列化,子类 ...
- Java中常见的名词解释
java 学习笔记指路 基础知识 Python转java补充知识 Java中常见的名词解释 前端 [黑马程序员pink老师前端]HTML [黑马程序员pink老师前端]JavaScript基础大总结 ...
- Java 中序列化与反序列化
一. 序列化和反序列化概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.将程序中的对象,放入文 ...
- java中序列化与反序列化
一.基本概念 1.序列化和反序列化的定义: (1)Java序列化就是指把Java对象转换为字节序列的过程Java反序列化就是指把字节序列恢复为Java对象的过程. (2)序列化最重要的作用:在传递和保 ...
- java中序列化怎么创建_【java】面试官问我,如何实现一个自定义序列化
通常离开内存的东西,如果需要存储或传输是需要序列化的,在java中要序列化是要实现Serializable的(或其子类),那不实现Serializable,如何实现一个自定义的序列化呢,我首先想到的是 ...
- Java中序列化的好处及意义
1.序列化是干什么的?简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存Object States, 但是Java给你提供一种应该比 ...
- JAVA中序列化的作用以及好处
1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存Object States,但是Java给你提供一种应该比 ...
- keypair java_如何在Java中序列化和反序列化RSA KeyPair
我想在我的Java应用程序中实现一些非常基本的安全性,但是一开始我就陷入了困境. 我想做的是这样的: 1-生成RSA密钥对 2将这些密钥以序列化形式存储在数据库中,以便在下次运行该应用程序时重新创建它 ...
最新文章
- 修改mysql参数_mysql动态修改参数
- Ubuntu下MySQL忘记root密码重置
- winfrom 点击按钮button弹框显示颜色集
- 计算机网络——链路层之局域网
- 互联网晚报 | 2月11日 星期五 | 小红书月活跃用户超2亿;小鹏汽车宣布拓展欧洲市场;贝壳首个青年公寓项目落地上海...
- SCCM Learning2
- mysql数据库在工控自动化应用_robotframework自动化系列:操作mysql数据库
- 联想p720装系统_教你装系统第六节(装系统需要注意那些?)
- 非平稳序列的随机性分析(SAS)
- 初级计算机硬件试题,初级计算机考试题库
- IOS版本APP STORE上架流程
- java adsl 拨号_[zt]利用脚本实现ADSL自动拨号上网
- 微信文章投诉模板html,微信小程序模板消息填坑
- 【超超超easy】5分钟:自制酷炫猫咪词云图,会点鼠标即可。
- root用户修改root密码提示The password fails the dictionary check
- TD-SCDMA与TD-LTE异构网络垂直切换算法
- 什么是android刷机包,刷机包是什么?ROM刷机包是什么意思?
- 人物-作家-马克·吐温:马克·吐温
- kubernetes之volumes使用
- TIA博途中变长数组的介绍与使用入门示例