千家信息网

JAVA序列号中serialVersionUID的示例分析

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章给大家分享的是有关JAVA序列号中serialVersionUID的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。serialVersionUID 的规范S
千家信息网最后更新 2026年11月03日JAVA序列号中serialVersionUID的示例分析

这篇文章给大家分享的是有关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序列号中serialVersionUID的示例分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

序列 对象 接口 方法 代码 时候 生成 变量 文件 一致 两个 序列号 二进制 关键 配置 示例 分析 关键字 内容 功能 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 湖北九亚互联网络科技有限公司 互联网属科技 科技互联网技术 美国互联网科技 中国互联网科技发展 宜安科技 互联网金融 米客互联网科技 互联网科技有限公司 翻译 互联网科技股午盘股票涨跌 互联网科技公司招聘 老年人脱离互联网科技的作文 剑昆互联网络科技有限公司临桂 宁夏科技产业互联网案例 互联网科技大奖都有哪些公司 翼展科技 首家互联网医院 互联网时代的科技公司 广州梦谷互联网科技有限公司领导 萌小萌互联网科技河南有限公司 现代互联网科技公司 上海旺乐尼互联网科技有限公司 互联网和科技技术 互联网品科技 科技企业和互联网企业 互联网科技与金融科技 上海互联网科技有限公司 茂名市互联网科技产业园 苏州五指互联网络科技有限 深圳育鹏互联网科技有限公司招聘 明优互联网科技有限公司 全球科技与互联网公司市值变化
0