-
为什么还要指定serialVersionUID的值?
-
不指定serialVersionUID出现的问题
-
Java 序列化的其他特性
-
static 属性为什么不会被序列化?
序列化:把对象转换为字节序列的过程称为对象的序列化.
反序列化:把字节序列恢复为对象的过程称为对象的反序列化.
在本地 JVM 里运行下 Java 实例,这个时候是不需要什么序列化和反序列化的
但当我们需要将内存中的对象持久化到磁盘,数据库中时, 当我们需要与浏览器进行交互时,或者当我们需要实现 RPC 时, 这个时候就需要序列化和反序列化了。
只要我们对JVM堆内存中的对象进行持久化或网络传输, 这个时候都需要序列化和反序列化.
JSON 格式实际上就是将一个对象转化为字符串, 所以服务器与浏览器交互时的数据格式其实是字符串,我们来看来 String 类型的源码:
public final class String
implements java.io.Serializable, Comparable, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
**String 类型实现了 Serializable 接口,并显示指定 serialVersionUID 的值.
也就是说我们使用Json进行传输字符串数据的时候, JVM已经将字符串数据序列化了**
在 Java 中实现了 Serializable 接口后, JVM 在类加载的时候就会发现我们实现了这个接口, 然后在初始化实例对象的时候就会在底层帮我们实现序列化和反序列化
如果不显示指定 serialVersionUID, JVM 在序列化时会根据属性自动生成一个 serialVersionUID, 然后与属性一起序列化,再进行持久化或网络传输。
在反序列化时,JVM 会再根据属性自动生成一个新版 serialVersionUID,然后将这个新版 serialVersionUID 与序列化时生成的旧版 serialVersionUID 进行比较,如果相同则反序列化成功, 否则报错.
如果显示指定了 serialVersionUID, JVM 在序列化和反序列化时仍然都会生成一个 serialVersionUID, 但值为我们显示指定的值, 就会进行serialVersionUID值的覆盖,这样在反序列化时新旧版本的 serialVersionUID 就一致了.
-
如果我们在不同的电脑上都有一个Person类, 我们想通过网络进行传输, 那就必须现在A电脑实现序列化, 在B电脑实现反序列化, 那么如果我们不指定serialVersionUID就就有可能反序列化失败
-
在实例开发过程中, 我们的类会经常改变, 如果我们使用JVM帮我们自动生成的serialVersionUID, 那么如果这个类已经有一些序列化对象, 那我们一旦修改了这个类,这些对象反序列化的时候就都会报错
写个实例测试下:
(1) User 类
不显示指定 serialVersionUID.
public class User implements Serializable {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return “User{” +
“name='” + name + ‘’’ +
“, age=” + age +
‘}’;
}
}
(2) 测试类
先进行序列化, 再进行反序列化.
public class DemoSerialVersionUID {
private static void serialize(User user) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File(“D:\test\111.txt”)));
oos.writeObject(user);
oos.close();
}
private static User deserialize() throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(“D:\test\111.txt”)));
return (User) ois.readObject();
}
public static void main(String[] args) throws Exception {
User user = new User();
user.setName(“Listen”);
user.setAge(22);
System.out.println("序列化前的结果: " + user);
serialize(user);
User dUser = deserialize();
System.out.println("反序列化后的结果: "+ dUser);
}
}
(3) 结果
先注释掉反序列化代码, 执行序列化代码, 然后 User 类新增一个属性 sex
public class User implements Serializable {
private String name;
private Integer age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
总结
谈到面试,其实说白了就是刷题刷题刷题,天天作死的刷。。。。。
为了准备这个“金三银四”的春招,狂刷一个月的题,狂补超多的漏洞知识,像这次美团面试问的算法、数据库、Redis、设计模式等这些题目都是我刷到过的
并且我也将自己刷的题全部整理成了PDF或者Word文档(含详细答案解析)
66个Java面试知识点
架构专题(MySQL,Java,Redis,线程,并发,设计模式,Nginx,Linux,框架,微服务等)+大厂面试题详解(百度,阿里,腾讯,华为,迅雷,网易,中兴,北京中软等)
算法刷题(PDF)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
66个Java面试知识点
架构专题(MySQL,Java,Redis,线程,并发,设计模式,Nginx,Linux,框架,微服务等)+大厂面试题详解(百度,阿里,腾讯,华为,迅雷,网易,中兴,北京中软等)
[外链图片转存中…(img-rT9LYACF-1713403006335)]
算法刷题(PDF)
[外链图片转存中…(img-vjC3litG-1713403006335)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!