1.什么是序列化和反序列化

  序列化就是将java对象转成字节序列的过程;反序列化就是将字节序列转成java对象的过程。

   java中,序列化的目的一种是需要将对象保存到硬盘上,一种是对象需要在网络中传输

2.序列化和反序列化的方式

  序列化和反序列化有很多种方式,如JDK类库中提供的序列化API、常用的json工具类等。本篇博客使用JDK提供的序列化API进行演示。重点说明serialVersionUID的作用。

  假设现在有一个Student类,我们要对Student类进行序列化操作

  ①该类必须实现Serializable接口

public class Student implements Serializable{

    private static final long serialVersionUID = -595470438262181967L;

    private String name ;

    private String sex;

    public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} }

  ②在main方法中执行序列化和反序列化操作

    public static void main(String[] args) throws Exception {

        //序列化
OutputStream os = new FileOutputStream(new File("D://student.txt"));
ObjectOutputStream oos = new ObjectOutputStream(os);
Student student = new Student();
student.setName("张三");
student.setSex("男");
oos.writeObject(student); //反序列化
InputStream is = new FileInputStream(new File("D://student.txt"));
ObjectInputStream ois = new ObjectInputStream(is);
Student student1 = new Student();
student1 = (Student) ois.readObject();
System.out.println(student1.getName());
}

  输出结果:张三

  即student1对象在反序列化时进行了赋值

3.为什么要serialVersionUID

  s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D​:​ ​字​面​意​思​上​是​序​列​化​的​版​本​号​,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量。

  (1)下面进行测试,如果没有s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D会出现什么?

    ①去掉Student类中的s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D属性。执行main方法,结果显示序列化成功!输出张三

    ②修改Student类,在Student类中添加number字段

public class Student implements Serializable{

    private String name ;

    private String sex;

    private String number;

    public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public String getNumber() {
return number;
} public void setNumber(String number) {
this.number = number;
} }

  不执行序列化方法,只执行反序列化方法,结果出现异常:

Exception in thread "main" java.io.InvalidClassException: com.iot.study.serialize.Student; local class incompatible: stream classdesc serialVersionUID = -595470438262181967, local class serialVersionUID = -4254220179260112271
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:621)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.iot.study.serialize.Client.main(Client.java:35)

  意思是原来序列化的时候(没有指定serialVersionUID)硬盘存的class的 serialVersionUID = -595470438262181967,而当前class的serialVersionUID = -4254220179260112271。 二者不一样,无法反序列化。

  原因分析:

    serialVersionUID没有指定时,java编译器会自动给这个class进行一个摘要算法,类似于指纹算法,只要这个文件 多一个空格,得到的UID就会截然不同的,可以保证在这么多类中,这个编号是唯一的。所以,添加了一个number字段后,由于没有显指定 serialVersionUID,编译器又为我们生成了一个UID,当然和前面保存在文件中的那个不会一样了,于是就出现了2个序列化版本号不一致的错误。

  (2)指定serialVersionUID测试

  如果为Student类显示的指定serialVersionUID,那么在序列化和反序列化的时候,即使修改了Student类中的部分内容,也能序列化成功。

4.serialVersionUID的取值

  serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。
  类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的 serialVersionUID,也有可能相同。为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值

  显式地定义serialVersionUID有两种用途:
    1、 在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;
    2、 在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。

java序列化和反序列化中的serialVersionUID有啥用的更多相关文章

  1. Java基础(五)-Java序列化与反序列化

    .output_wrapper pre code { font-family: Consolas, Inconsolata, Courier, monospace; display: block !i ...

  2. (记录)Jedis存放对象和读取对象--Java序列化与反序列化

    一.理论分析 在学习Redis中的Jedis这一部分的时候,要使用到Protostuff(Protobuf的Java客户端)这一序列化工具.一开始看到序列化这些字眼的时候,感觉到一头雾水.于是,参考了 ...

  3. java序列化和反序列化使用总结

    一.概念 java对象序列化的意思就是将对象的状态转化成字节流,以后可以通过这些值再生成相同状态的对象.对象序列化是对象持久化的一种实现方法,它是将对象的属性和方法转化为一种序列化的形式用于存储和传输 ...

  4. java 序列化和反序列化的底层实现原理

    出处:序列化和反序列化的底层实现原理是什么? 一.基本概念1.什么是序列化和反序列化 (1)Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过 ...

  5. Java 序列化和反序列化(三)Serializable 源码分析 - 2

    目录 Java 序列化和反序列化(三)Serializable 源码分析 - 2 1. ObjectStreamField 1.1 数据结构 1.2 构造函数 2. ObjectStreamClass ...

  6. Java 序列化和反序列化(二)Serializable 源码分析 - 1

    目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputSt ...

  7. Java 序列化和反序列化(一)Serializable 使用场景

    目录 Java 序列化和反序列化(一)Serializable 使用场景 1. 最简单的使用:Serializable 接口 2. 序列化 ID 的问题 3. 静态字段不会序列化 4. 屏蔽字段:tr ...

  8. java序列化与反序列化的使用

    个人博客 地址:http://www.wenhaofan.com/article/20180925214701 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字 ...

  9. Serializable详解(1):代码验证Java序列化与反序列化

    说明:本文为Serializable详解(1),最后两段内容在翻译上出现歧义(暂时未翻译),将在后续的Serializable(2)文中补充. 介绍:本文根据JDK英文文档翻译而成,本译文并非完全按照 ...

随机推荐

  1. 2017 cinemachine

    只有2017以上才可以使用~ 导入Asset store中的cinemachine,会在上方显示cinemachine.每创建一个虚拟摄像机,就会在主摄像机下创建组件  cinemachine Bra ...

  2. HDFS基本Shell命令

    bin目录下: 1. hadoop fs 基本操作命令,类似linux shell 2. hadoop dfsadmin    管理命令 3. hadoop fsck (1. 检查hdfs中文件的健康 ...

  3. 【python】问题汇总

    1.pip降级 python -m pip install pip==9.0.3 2. Flask利用pymysql出现Warning:1366的解决办法 错误提示:(1366, "Inco ...

  4. 【druid 】数据库连接池-sql解析

    https://segmentfault.com/a/1190000008120254?utm_source=tuicool&utm_medium=referral sql解析 Druid 的 ...

  5. Spring MVC的原理及配置详解

    网址链接:https://www.cnblogs.com/baiduligang/p/4247164.html

  6. python 常用库

    Numpy, Pandas 数据处理 Scipy  科学计算 Matplotlib 可视化 Scikit Learn  机器学习 Keras 深度学习模型 jieba 分词 Gensim  主题(包含 ...

  7. 【转】Python高级知识点总结

    一.可迭代对象.迭代器对象和生成器 像list, tuple等这些序列是可以使用for...in ...语句来进行遍历输出的.这是为什么呢?这就需要知道可迭代对象(Iterable).迭代器对象(It ...

  8. Centos7下安装pptp客户端

    1.使用yum安装ppp和pptp yum install ppp pptp 2.配置pptp pptpsetup --create vpn连接名称(自定义) --server VPN服务器IP -- ...

  9. Nodejs+MQTT

    客户端 https://github.com/mqttjs/MQTT.js 服务端 https://github.com/mcollina/mosca ionci3 使用mqtt.js   Brosw ...

  10. docker的windows环境设置

    1.下载docker-install.exe安装VirtualBox.Git.Boot2Docker for Windows 2.设置环境变量,启动boot2docker Core Linux. 可以 ...