Java序列化之serialVersionUID

今天讲一讲Java对象中的serialVersionUID,先从序列化讲起。

什么是序列化

序列化,简单的说,就是将一个对象转化(编码)成可以传输的输出流(字节流)。而反序列化就是序列化的逆过程,将输入流转化(构建)成一个对象。

为什么要序列化

字节流可以用于网络传输和存储在磁盘,而对象需要转化成字节流才能在网络中传输和在磁盘上存储。
网络传输就好比打电话,声音是无法直接从电话的一端传到另一端,因此需要将声音转成电信号进行传播。
另一方面,Java对象是保存在JVM的堆内存中的,也就是说,如果JVM堆不存在了,那么对象也就跟着消失了,而序列化提供了可以把对象保存下来的方案。

serialVersionUID是个啥

说到序列化,serialVersionUID是个不得不谈的话题。serialVersionUID 是 Java 为每个序列化类(实现java.io.Serializable接口的类)产生的版本标识, 可用来保证在反序列时,发送方发送的和接受方接收的是可兼容的对象。 如果接收方接收的类的 serialVersionUID 与发送方发送的 serialVersionUID 不一致,进行反序列时会抛出 InvalidClassException。

怎么生成serialVersionUID

下载GenerateSerialVersionUID插件,就可以自动生产这个序列类的serialVersionUID了,具体过程可参考链接.

serialVersionUID是一成不变的吗

达咩!
serialVersionUID 是 Java 为每个序列化类产生的版本标识!!
Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用。如果Class文件的类名、方法名称发生改变,serialVersionUID就会改变。如果Class文件没有发生变化(增加空格,换行,增加注释等等),就算再编译多次,serialVersionUID也不会变化的。

import java.io.Serializable;public class Person implements Serializable {// 原本的serialVersionUIDprivate static final long serialVersionUID = 904XXXXXXXXXX662L;private int age;private String name;private String address;public Person(int age, String name, String address) {this.age = age;this.name = name;this.address = address;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}
import java.io.Serializable;public class Person implements Serializable {// 加上toSting函数的serialVersionUIDprivate static final long serialVersionUID = 841XXXXXXXXXXXXX884L;private int age;private String name;private String address;public Person(int age, String name, String address) {this.age = age;this.name = name;this.address = address;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Person{" +"age=" + age +", name='" + name + '\'' +", address='" + address + '\'' +'}';}
}

如果我手动改了serialVersionUID=11111111L会怎样?如果接收方接收的类的 serialVersionUID 与发送方发送的 serialVersionUID 不一致,进行反序列时会抛出 InvalidClassException。

Exception in thread "main" java.io.InvalidClassException: SerializableStudy.Person; local class incompatible: stream classdesc serialVersionUID = 841XXXXXXXXXXXXX884, local class serialVersionUID = 11111111

序列化和反序列化

序列化要把对象写入输出流中,反序列化就是将输出流重新构建对象,二者为逆过程。当serialVersionUID改变时,一定要重新序列化,再进行反序列化。话不多说,放代码。以下是基于上面序列化类Person,做序列化和反序列化的演示:

public class SerialTest {public static void main(String[] args) throws IOException {//        序列化Person p = new Person(0,"aaa","bbbbb");
//        指定文件生成输出流FileOutputStream fos = new FileOutputStream("person.txt");
//        将对象写出到指定的输出流ObjectOutputStream oos = new ObjectOutputStream(fos);
//        将指定的对象写入ObjectOutputStream。oos.writeObject(p);
//        刷新流oos.flush();oos.close();}
}
public class DeserialTest {public static void main(String[] args) throws IOException, ClassNotFoundException {//        反序列化
//        根据指定文件生产输入流FileInputStream fis = new FileInputStream("person.txt");
//        从指定的输入流中读回对象消息ObjectInputStream ois = new ObjectInputStream(fis);
//        从ObjectInputStream读取一个对象Person p = (Person) ois.readObject();ois.close();System.out.println(p.toString());}
}

输出的结果为

注意:
将指定对象写入ObjectOutputStream时,存储针对对象本身而不是针对类,没有实现序列化的类不会参与序列化和反序列化!!举个例子,如果Person中设置一个没有实现序列化的父类Home:

public class Home {private String home;public String getHome() {return home;}public void setHome(String home) {this.home = home;}
}
public class Person extends Home implements Serializable {......
}

在序列化和反序列化的过程中,即使定义了Person对象的home属性,由于Home中没有实现序列类,因此对象的home属性不会进行序列化处理。

Java序列化之serialVersionUID相关推荐

  1. 探析“Java序列化”之serialVersionUID

    未显式指定serialVersionUID 当没有显式地定义serialVersionUID变量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本,它 ...

  2. java 序列化 uid_一文看懂Java序列化之serialVersionUID

    serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...

  3. hessian java_Hessian和java序列化对比

    java的序列化 ​1.Java序列化的性能经常被吐槽. 2.Java序列化后的数据相对于一些优秀的序列化的工具,还是要大不少,比如probuf,这大大影响存储和传输的效率. 3.Java序列化一定需 ...

  4. java 四字节uid,Java入门教程-序列化版本号serialVersionUID的作用

    原标题:Java入门教程-序列化版本号serialVersionUID的作用 Java序列化是将一个对象编码成一个字节流,反序列化将字节流编码转换成一个对象.序列化是Java中实现持久化存储的一种方法 ...

  5. java 序列化版本号_序列化版本号serialVersionUID的作用

    原标题:序列化版本号serialVersionUID的作用 Java序列化是将一个对象编码成一个字节流,反序列化将字节流编码转换成一个对象.序列化是Java中实现持久化存储的一种方法:为数据传输提供了 ...

  6. Java序列化的机制和原理

    有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍. Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述 ...

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

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

  8. java 中的 serialVersionUID

    2019独角兽企业重金招聘Python工程师标准>>> private static final long serialVersionUID = 1L; Java的序列化机制是通过判 ...

  9. java序列化和RMI

    深入了解序列化"契约" 由于Java提供了良好的默认支持,实现基本的对象序列化是件比较简单的事.待序列化的Java类只需要实现Serializable接口即可.Serializab ...

最新文章

  1. linux运行dock打包的镜像,Linux部署之Docker方式部署项目
  2. Asp.net MVC2.0系列文章-添加操作
  3. ASP.NET Web API Selfhost宿主环境中管道、路由
  4. golang zerolog包使用
  5. c语言 listview,C语言 SDK编程之通用控件的使用--ListView
  6. ScrollView 分割屏幕效果
  7. MYSQL中用正则筛选一定的数据
  8. 过直线上一点画垂线图_苏教版四年级数学上册8.5认识垂直、点到直线的距离微课视频 | 练习...
  9. Android studio 运行即打包keystore之build.gradle设置
  10. python增删改查csv文件_Python增删改查文件
  11. 《C和指针》——stdarg宏简介
  12. java冒险岛_JAVA开发类似冒险岛的游戏Part1
  13. 质数筛+埃氏筛取思想
  14. kubernetes的eviction机制
  15. siteapp–让独立博客变成手机app
  16. chrome主页篡改修复
  17. song -用函数画彩虹
  18. 清华大学计算机系前景好么,华为正式宣布选择西工大,而不是清华计算机系,网友:为什么?...
  19. CSUOJ1238--兵临城下
  20. 银河麒麟桌面操作系统V10上安装使用MySQL5.7、MySQL Workbench

热门文章

  1. 无法解析的外部符号解决方法汇总
  2. 笔记本电脑无法连接WiFi?找不到WiFi图标?(图解)
  3. 小程序隐藏顶栏或是自定义
  4. Cesium加载天地图山东WMTS服务(weixin公众号【图说GIS】)
  5. keepalived的vip无法ping通排查过程
  6. IDEA之Maven配置
  7. 韶关市哪里的房子比较好?
  8. 如何使用python语言调用旷世(Face++)应用
  9. 记录自己学到东西-2017-08-26
  10. iPhone 8无线充电会很好,但这方面三星快充手机更好,你承认吗?