序列号 java_JAVA序列号的serialVersionUID
serialVersionUID 的规范
Serializable 和 Externalizable
Java类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法进行序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。
如果读者看过Serializable的源码,就会发现,他只是一个空的接口,里面什么东西都没有。Serializable接口没有方法或字段,仅用于标识可序列化的语义。但是,如果一个类没有实现这个接口,想要被序列化的话,就会抛出java.io.NotSerializableException异常。
序列号在写成二进制流的时候,会调用如下的方法:
Externalizable继承自Serializable,该接口中定义了两个抽象方法:writeExternal()与readExternal()。
当使用Externalizable接口来进行序列化与反序列化的时候需要开发人员重写writeExternal()与readExternal()方法。否则所有变量的值都会变成默认值。
transient 不需要被序列化
transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。
什么是 serialVersionUID
序列化是将对象的状态信息转换为可存储或传输的形式的过程。我们都知道,Java对象是保存在JVM的堆内存中的,也就是说,如果JVM堆不存在了,那么对象也就跟着消失了。
而序列化提供了一种方案,可以让你在即使JVM停机的情况下也能把对象保存下来的方案。就像我们平时用的U盘一样。把Java对象序列化成可存储或传输的形式(如二进制流),比如保存在文件中。这样,当再次需要这个对象的时候,从文件中读取出二进制流,再从二进制流中反序列化出对象。
虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致,这个所谓的序列化ID,就是我们在代码中定义的serialVersionUID。
这是因为,在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。
为什么必须设置默认的 serialVersionUID 值
如果我们没有在类中明确的定义一个serialVersionUID的话,看看会发生什么。
尝试修改上面的demo代码,先使用以下类定义一个对象,该类中不定义serialVersionUID,将其写入文件。
然后我们修改User1类,向其中增加一个属性。在尝试将其从文件中读取出来,并进行反序列化。
执行结果:
java.io.InvalidClassException: com.hollis.User1; local class incompatible: stream classdesc serialVersionUID = -2986778152837257883, local class serialVersionUID = 7961728318907695402
同样,抛出了InvalidClassException,并且指出两个serialVersionUID不同,分别是-2986778152837257883和7961728318907695402。
从这里可以看出,系统自己添加了一个serialVersionUID。
所以,一旦类实现了Serializable,就建议明确的定义一个serialVersionUID。不然在修改类的时候,就会发生异常。
serialVersionUID有两种显示的生成方式:
一种是默认的1L,比如:
private static final long serialVersionUID = 1L;
另外一种是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
private static final long serialVersionUID = xxxxL;
后面这种方式,可以借助IDE生成,后面会介绍。
背后原理
为了简化代码量,反序列化的调用链如下:
在initNonProxy中 ,关键代码如下:
在反序列化过程中,对serialVersionUID做了比较,如果发现不相等,则直接抛出异常。
深入看一下getSerialVersionUID方法:
在没有定义serialVersionUID的时候,会调用computeDefaultSUID 方法,生成一个默认的serialVersionUID。
这也就找到了以上两个问题的根源,其实是代码中做了严格的校验,并且在未定义的时候自动生成了一个serialVersionUID。
IDEA提示
为了确保我们不会忘记定义serialVersionUID,可以调节一下Intellij IDEA的配置,在实现Serializable接口后,如果没定义serialVersionUID的话,IDEA(eclipse一样)会进行提示:
并且可以一键生成一个:
当然,这个配置并不是默认生效的,需要手动到IDEA中设置一下:
在图中标号3的地方(Serializable class without serialVersionUID的配置),打上勾,保存即可。
序列号 java_JAVA序列号的serialVersionUID相关推荐
- iphonex 序列号_iPhonex如何查看序列号 iPhonex序列号查看有哪些方法
iPhonex很多小伙伴已经入手了,初使用iPhonex的小伙伴对于iPhonex还不是很熟悉,一些小伙伴想知道iPhonex如何查看序列号,下面就让小编为大家介绍一下iPhonex序列号查看方法,感 ...
- c# 获取本机 MAC地址\序列号\硬盘序列号
View Code 1 /// <summary> 2 /// 显示MAC地址 3 /// </summary> 4 ...
- 用C#获取硬盘序列号,CPU序列号,网卡MAC地址
这个问题首先得考虑的就是你的硬盘是不是SCSI硬盘 如果是,那么根本不存在"物理序列号",只可能取得卷标的序列号 如果是卷标序列号,要注意的是每次格式化硬盘的时候这个序列号都会变 ...
- Python获取硬件信息(硬盘序列号,CPU序列号)
原文衔接 https://www.cnblogs.com/blog-rui/p/12108072.html pip install wmi pip install pywin32 import wmi ...
- iphonex 序列号_iPhoneX序列号在哪 苹果X序列号怎么看?
对于后续准备入手iPhoneX的果粉来说,很多朋友拿到真机之后都想知道自己买到是不是正品.水货之类的.其实一般情况下除了通过外观真机.配件之外去辨别之外,我们还可以通过iPhoneX序列号去查看.对于 ...
- iphonex 序列号_iPhoneX序列号在哪?苹果iPhoneX序列号怎么看?
iPhoneX怎么辨别真假?iPhoneX序列号在哪?苹果iPhoneX序列号怎么看?很多朋友拿到苹果X真机之后不确定知道自己买到的是不是正品.水货之类的.从外观.配件又不好辨别,此事我们可以通过iP ...
- 思科序列号无服务器,查看思科设备序列号以及序列号的命名格式
对于思科网络设备来说,设备的序列号(Serial Number)至关重要,序列号是出厂的时候就决定的唯一标识,在网络工程师的日常工作中,可能经常需要和序列号打交道.那么具体我们应该如何查看这些序列号, ...
- iphonex 序列号_iPhonex序列号在哪看?iPhonex序列号查看方法介绍[图]
最近关于iphonex的各种消息不断,可以看出来这款手机真的很受欢迎,很多网友在问,对于iphonex的正版序列号怎么查询还不太清楚,那么这个序列号在哪儿看呢?安族小编整理了资料和大家分享下吧! iP ...
- 序列号及序列号生成器(号段模式,数据库模式)详细介绍(建议收藏)
前言 现如今,数据的唯一性和可追溯性变得越来越重要.从简单的数据库主键到复杂的分布式系统,唯一标识符在各种场景中都发挥着关键作用.序列号,作为一种广泛应用的唯一标识符,为我们提供了确保数据完整性和一致 ...
- mysql 模拟 序列号_mysql 序列号生成器(转)
如果你不想使用mysql的自动递增,但又想实现主键序列号的功能,可以使用下面的方法,通过函数用一张表去维护生成多个表的序列号,简单又实用 1.创建生成多个表的序列号的数据维护表 CREATE TABL ...
最新文章
- ARCGIS影像配准教程
- 【撸啊撸 Docker】搭建 Jenkins
- JavaScript 严格模式(use strict)
- jquery ajax 跨域请求
- 成都理工大学“自然地理学”专业转行AI之路(精彩直播回放)
- 90%做tiktok运营都存在的误区?
- 谷歌Chrome浏览器无法打开网页,提示您与此网站之间建立不安全连接【解决】
- C陷阱与缺陷-1理解函数申明
- K60笔记2——内存空间分布
- 一个简单易用的m3u8下载器,支持下载m3u8链接或文件为mp4或ts格式
- 电脑屏幕网页字体大小怎么调整?
- 电视机关机特效——android
- mysql sock_mysql.sock 文件解析
- 深入理解栈(Stack)
- XFP模块和SFP光模块
- Hotspot Object本地方法实现 源码解析
- python 生成器、列表/字典/集合解析式区别
- 水晶报表 小代码大作用【BY 阿泰】
- C语言—递归函数有5个人围坐在一起,问第5个人多大年纪,他说比第4个人大2岁;问第4个人,他说比第3个人大2岁;问第3个人,他说比第2个人大2岁;问第2个人,他说比第1个人大2岁。第1个人说自己10岁
- 扒开思派健康招股书:大数据的面子,“卖药”的里子
热门文章
- word打开文档很久很慢_打开Office文档很慢的解决办法
- ltm是什么门的缩写_公司简报中的“LTM EBITDA”是什么意思啊?对应的中文是什么?...
- R语言-豆瓣电影top250数据爬取和分析
- 对JavaWeb项目中WEB-INF目录的理解
- 【Java】抽象类和接口的区别
- 伦敦银持仓分布分析技巧
- dismiss ios pop效果_动画切换效果之push、pop、present、dismiss
- 向flume发送消息出现Client sent event exceeding the maximum length
- 【玩转linux】head命令
- 【Unity3D日常开发】Unity3D中实现箭头指向目标点的效果