Java序列化之serialVersionUID
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相关推荐
- 探析“Java序列化”之serialVersionUID
未显式指定serialVersionUID 当没有显式地定义serialVersionUID变量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本,它 ...
- java 序列化 uid_一文看懂Java序列化之serialVersionUID
serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...
- hessian java_Hessian和java序列化对比
java的序列化 1.Java序列化的性能经常被吐槽. 2.Java序列化后的数据相对于一些优秀的序列化的工具,还是要大不少,比如probuf,这大大影响存储和传输的效率. 3.Java序列化一定需 ...
- java 四字节uid,Java入门教程-序列化版本号serialVersionUID的作用
原标题:Java入门教程-序列化版本号serialVersionUID的作用 Java序列化是将一个对象编码成一个字节流,反序列化将字节流编码转换成一个对象.序列化是Java中实现持久化存储的一种方法 ...
- java 序列化版本号_序列化版本号serialVersionUID的作用
原标题:序列化版本号serialVersionUID的作用 Java序列化是将一个对象编码成一个字节流,反序列化将字节流编码转换成一个对象.序列化是Java中实现持久化存储的一种方法:为数据传输提供了 ...
- Java序列化的机制和原理
有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍. Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述 ...
- java基础(十)-----Java 序列化的高级认识
将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口,使用 ...
- java 中的 serialVersionUID
2019独角兽企业重金招聘Python工程师标准>>> private static final long serialVersionUID = 1L; Java的序列化机制是通过判 ...
- java序列化和RMI
深入了解序列化"契约" 由于Java提供了良好的默认支持,实现基本的对象序列化是件比较简单的事.待序列化的Java类只需要实现Serializable接口即可.Serializab ...
最新文章
- linux运行dock打包的镜像,Linux部署之Docker方式部署项目
- Asp.net MVC2.0系列文章-添加操作
- ASP.NET Web API Selfhost宿主环境中管道、路由
- golang zerolog包使用
- c语言 listview,C语言 SDK编程之通用控件的使用--ListView
- ScrollView 分割屏幕效果
- MYSQL中用正则筛选一定的数据
- 过直线上一点画垂线图_苏教版四年级数学上册8.5认识垂直、点到直线的距离微课视频 | 练习...
- Android studio 运行即打包keystore之build.gradle设置
- python增删改查csv文件_Python增删改查文件
- 《C和指针》——stdarg宏简介
- java冒险岛_JAVA开发类似冒险岛的游戏Part1
- 质数筛+埃氏筛取思想
- kubernetes的eviction机制
- siteapp–让独立博客变成手机app
- chrome主页篡改修复
- song -用函数画彩虹
- 清华大学计算机系前景好么,华为正式宣布选择西工大,而不是清华计算机系,网友:为什么?...
- CSUOJ1238--兵临城下
- 银河麒麟桌面操作系统V10上安装使用MySQL5.7、MySQL Workbench