Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >为什么实现了Serializable接口还要指定serialVersionUID值呢?

为什么实现了Serializable接口还要指定serialVersionUID值呢?

作者头像
Lvshen
发布于 2022-05-05 09:31:44
发布于 2022-05-05 09:31:44
71800
代码可运行
举报
运行总次数:0
代码可运行

什么是序列化与反序列化

你在平时的开发中肯定发现实体类会实现Serializable接口,并且指定serialVersionUID的值。像这样

你可能会有疑问,为什么要实现Serializable接口呢。实现这个接口是为了序列化和反序列化。

如果这个实体类有内存和硬盘的数据交互,或者内存与网络的数据交互时,就需要序列化和反序列化了。这时不实现Serializable接口就会出现java.io.NotSerializableException异常。

那么什么是序列化和反序列化呢?

“序列化:将对象转换成字节序列的过程 反序列化:将字节序列恢复成对象的过程 ”

所以如果你编写的实体类不需要与硬盘交互。比如这个对象装载的数据不用存储在数据库,或者不需要网络传递(比如发送到KafkaRedis等)。就不用实现Serializable

不知你发现了没,我们平时数据传输用的JSON格式实际就是将对象转换成字符串了。我们来看看String的源码

String不仅实现了Serializable接口还指定了serialVersionUID的值。

你可能会有疑问,已经实现Serializable了,为什么一定要指定serialVersionUID的值呢?

为什么还要指定serialVersionUID

定义实体类

我们来举个例子,先写一个实体类:

这里我们不指定serialVersionUID值,来看看会有什么影响。

编写方法

1.将实体封装数据的实体写到文件中(内存 -> 硬盘),这里就是序列化。

2.将文件中的数据转成实体(硬盘 -> 内存),这里是反序列化。

测试

测试结果

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
序列化前:UserInfo(name=Lvshen, hobby=看书)
反序列化后:UserInfo(name=Lvshen, hobby=看书)

数据成功从内存写进文件,并且成功从文件读取出来。

修改实体

这时我们在UserInfo里面添加一个新字段address

直接反序列化

然后注释掉序列化的方法,我们再从文件读取数据

测试结果如下:

发现序列化的serialVersionUID值和反序列化的serialVersionUID不一致。导致InvalidClassException异常。

当我们在最开始时指定

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Data
public class UserInfo implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;  //姓名
    private String hobby; //爱好
   
}

然后再走一遍上面的流程【序列化 -> 反序列化 -> 修改实体 -> 反序列化】。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
序列化前:UserInfo(name=Lvshen, hobby=看书, address=null)
反序列化后:UserInfo(name=Lvshen, hobby=看书, address=null)

发现就算新增了address字段,还是能正常反序列化。

当对同一个实体序列化反序列化时,需要serialVersionUID值一致才能成功。如果我们不显示指定serialVersionUID,在序列化时会自动生成一个serialVersionUID。当实体类改动了,反序列化时,会生成一个新serialVersionUID。这两个serialVersionUID的值肯定不一致,从而反序列化会失败。但是如果显示指定,就不会生成新serialVersionUID值了。反序列化的serialVersionUID就是原序列化的serialVersionUID

实际开发中实体类肯定会不断迭代修改的,所以指定一个显示的serialVersionUID值,就不用担心序列化和反序列化的问题了。

下列情况可以不需要serialVersionUID

  • 如果你的实体类新增的属性被static修饰的,这个属性就不会被序列化。
  • 或者实体类有个属性被transient修饰,修改transient的值也不会被影响(不会被序列化)。

大家可以思考,如果需要序列化被这两种关键字修饰的属性,该怎么做呢?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Lvshen的技术小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java Serializable 序列化学习笔记 及transient关键字 及 serialVersionUID 作用
Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。
大鹅
2021/06/16
5220
Java程序员必备:序列化全方位解析
如果想在JVM停止后,把这些对象保存到磁盘或者通过网络传输到另一远程机器,怎么办呢?磁盘这些硬件可不认识Java对象,它们只认识二进制这些机器语言,所以我们就要把这些对象转化为字节数组,这个过程就是序列化啦~
捡田螺的小男孩
2020/05/01
1.9K0
java的serializable接口_javacloneable接口
clone:它允许在堆中克隆出一块和原对象一样的对象,并将这个对象的地址赋予新的引用。 Java 中 一个类要实现clone功能 必须实现 Cloneable接口,否则在调用 clone() 时会报 CloneNotSupportedException 异常。
全栈程序员站长
2022/11/04
1.1K0
serialVersionUID详解「建议收藏」
简单来说,Java的序列化机制是通过类的serversionUID来验证版本一致性的。在反序列化时,JVM会将传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。
全栈程序员站长
2022/09/07
9330
面试被问Java序列化和反序列化为什么要实现Serializable接口
最近公司的在做服务化, 需要把所有model包里的类都实现Serializable接口, 同时还要显示指定serialVersionUID的值. 听到这个需求, 我脑海里就突然出现了好几个问题, 比如说:
程序员白楠楠
2021/02/25
1.1K0
transient关键字
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说transient关键字,希望能够帮助大家进步!!!
Java架构师必看
2022/01/12
4710
Serializable是什么
序列化:对象的寿命通常随着生成该对象的程序的终止而终止,有时候需要把在内存中的各种对象的状态(也就是实例变量,不是方法)保存下来,并且可以在需要时再将对象恢复。虽然你可以用你自己的各种各样的方法来保存对象的状态,但是Java给你提供一种应该比你自己的好的保存对象状态的机制,那就是序列化。
用户4396583
2024/08/13
1470
java 序列化Serializable
张工是一名java程序员,工作5年了,一直从事java开发。最近到某互联网公司面试,做了笔试题后,有一道笔试题是这样子的:Serializable有什么作用,张工没有作答,面谈时面试官又问了,张工回答不出个所以然。面试官:你都工作五年了,连序列化都不知道,你这5年都干些什么了?张工一脸的无助,不过确实不应该,类似Serializable序列化这样的知识点,平时应该不会少用。
葫芦
2019/10/24
6260
详细聊聊 Java序列化和反序列化的作用
如果你看过某些类的源码或者公司的项目,有一些类是实现 Serializable 接口,同时还要显示指定 serialVersionUID 的值。
HaC
2021/03/09
1.4K0
详细聊聊 Java序列化和反序列化的作用
Java 序列化 之 Serializable
概念 序列化:就是把对象转化成字节。 反序列化:把字节数据转换成对象。 对象序列化场景: 1、对象网络传输 例如:在微服务系统中或给第三方提供接口调用时,使用rpc进行调用,一般会把对象转化成字节序列,才能在网络上传输;接收方则需要把字节序列再转化为java对象。 2、对象保存至文件中 例如:hibernate中的二级缓存:把从数据库中查询出的对象,序列化转存到硬盘中,下次读取的时候,首先从内存中找是否有该对象,如果没有在去二级缓存(硬盘)中去查找。减少数据库的查询次数,提升性能。 3、tomcat的
java404
2018/05/18
9490
Java序列化,看这篇就够了
Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程:
说故事的五公子
2021/02/02
2.8K1
面试官:说说你对序列化的理解
在Java语言中,程序运行的时候,会产生很多对象,而对象信息也只是在程序运行的时候才在内存中保持其状态,一旦程序停止,内存释放,对象也就不存在了。
田维常
2020/12/14
4110
面试长知识了!Java 关键字 transient 竟然还能这么用
最近在看 HashMap 源代码的时候,发现链表 table 数组采用了transient 关键字,笔者当时感觉对 transient 关键字即陌生但又有似曾相识,所以花了一些时间简要的总结了下使用transient 关键字的一些基本常识,希望对你们也有些帮助,让我们一起进步,一起牛逼吧。
用户4172423
2021/04/02
4.1K0
面试长知识了!Java 关键字 transient 竟然还能这么用
Android Activity间传值选择,Serializable Or Parcelable
  前言:Activity就是Android世界的controller,它们构成了Android App里面的每一个页面,当然我们还会使用Fragment来将页面进一步划分,通过Fragment可以对特定业务模块的View+逻辑封装,让其与Activity解耦,同时还可以有自己的生命周期,让我们控制布局绘制和进行资源回收,这些都是Fragment的好处,以后有机会再谈,今天,我们想讨论的是Activity页面之间跳转时,互相传值的方法选择。
三好码农
2018/09/11
1.4K0
Android Activity间传值选择,Serializable Or Parcelable
Serializable接口心得总结
可以看到该类的内部实现完全为空,在Java IO体系中仅起一个标记的作用。那么这个标记具体是如何发挥作用的呢?我们测试一下:
Remember_Ray
2020/01/21
4430
【Java 基础篇】Java 对象流与序列化
在 Java 编程中,对象的序列化是指将对象转换为字节序列,以便可以将其存储到文件、内存中进行传输或在网络上进行传输。反序列化则是将字节序列重新转换为对象。Java 提供了对象流来实现对象的序列化和反序列化操作。
繁依Fanyi
2023/10/12
3230
Java对象为啥要实现Serializable接口?
最近这段时间一直在忙着编写Java业务代码,麻木地搬着Ctrl-C、Ctrl-V的砖,在不知道重复了多少次定义Java实体对象时“implements Serializable”的C/V大法后,脑海中突然冒出一个思维(A):问了自己一句“Java实体对象为什么一定要实现Serializable接口呢?”,关于这个问题,脑海中的另一个思维(B)立马给出了回复“居然问这么幼稚和基础的问题,实现Serilizable接口是为了序列化啊!”,思维(A):“哦,好吧!然而,然后呢?”
用户5927304
2019/07/30
1.1K0
Java对象为啥要实现Serializable接口?
Java 之 Serializable 序列化和反序列化的概念,作用的通俗易懂的解释[通俗易懂]
遇到这个 Java Serializable 序列化这个接口,我们可能会有如下的问题 a,什么叫序列化和反序列化 b,作用。为啥要实现这个 Serializable 接口,也就是为啥要序列化 c,serialVersionUID 这个的值到底是在怎么设置的,有什么用。有的是1L,有的是一长串数字,迷惑ing。 我刚刚见到这个关键字 Serializable 的时候,就有如上的这么些问题。
全栈程序员站长
2022/11/01
9330
Java 之 Serializable 序列化和反序列化的概念,作用的通俗易懂的解释[通俗易懂]
JDK1.9-序列化
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
cwl_java
2019/12/10
4700
JDK1.9-序列化
Java 序列化
序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例。
HLee
2021/05/08
1.2K0
Java 序列化
相关推荐
Java Serializable 序列化学习笔记 及transient关键字 及 serialVersionUID 作用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验