详解Java中的serialVersionUID概念以及作用(附上Demo)

2024-01-09 10:20

本文主要是介绍详解Java中的serialVersionUID概念以及作用(附上Demo),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 前言
  • 1. 概念
  • 2. Demo

前言

原本实现Serializable接口的时候一直都没有serialVersionUID属性,直到看到涉及MybatisPlus新项目中都有该属性,于是做了一期学习了解,最后发现该属性类似深度学习训练中的种子seed,类似版本控制!

1. 概念

serialVersionUID 是 Java 中用于版本控制序列化的一个字段。

手动方式默认值为1L,比如:private static final long serialVersionUID = 1L

  • 一个长整型数值
  • 是一个 private static final long 类型的字段,用于标识一个类的序列化版本号
  • 在序列化和反序列化过程中,serialVersionUID 被用来验证序列化对象和反序列化对象的类是否兼容,即是否是同一个类的不同版本。
作用(为什么需要)生成方式(功能意义)注意事项
1.用于标识类的版本,确保序列化和反序列化的兼容性。如果两个类的 serialVersionUID 不同,Java 将不会进行序列化和反序列化,以避免版本不一致导致的问题。

2.冲突解决: 在类的结构发生变化时,通过手动指定 serialVersionUID 可以防止默认生成的版本号发生变化,从而避免潜在的冲突。
1.自动生成: 如果一个类没有显式声明 serialVersionUID,Java 序列化机制会根据类的结构自动生成一个版本号。

2.手动生成: 开发人员可以通过手动在类中定义 private static final long serialVersionUID 来指定版本号,以便在类结构发生变化时能够更加精确地控制版本。
1.如果不显式指定 serialVersionUID,Java 将根据类的结构自动生成。这种自动生成的方式可能不够稳定,因此在需要进行序列化的类中最好显式指定 serialVersionUID。

2.当类的结构发生变化时,手动指定 serialVersionUID 可以防止默认生成的版本号发生变化,避免潜在的序列化问题。

类似的代码如下:

import java.io.Serializable;public class MyClass implements Serializable {private static final long serialVersionUID = 1L;// other class members and methods
}

在这个示例中,MyClass 类显式地指定了 serialVersionUID 为 1L,以确保在类的结构发生变化时能够更好地进行版本控制

对于Serializable 类,其源码只是一个接口:public interface Serializable { }

总的来说:

serialVersionUID 是根据类的结构计算得到的哈希值,通常为负数。这个值是通过对类的结构进行哈希运算而生成的,因此不同版本的类将具有不同的 serialVersionUID。其存在的主要目的是为了处理序列化和反序列化过程中的版本兼容性问题。

当一个类被序列化后,其字节表示可能会存储在磁盘上或通过网络传输到不同的 JVM(Java 虚拟机)。如果类的结构发生了变化,例如添加了新的字段或方法,反序列化时就可能出现版本不一致的问题。为了解决这个问题,引入了 serialVersionUID 的概念。

以下是对 serialVersionUID 的功能和作用的总结:

  • 版本兼容性
    serialVersionUID 的存在是为了确保序列化和反序列化的版本兼容性。
    当类的结构发生变化时,不同版本的类将具有不同的 serialVersionUID。
    在序列化和反序列化过程中,Java 使用 serialVersionUID 来验证类的版本是否一致,以防止版本不匹配引发的问题。

  • 自动生成和手动生成:(上述已阐述)

  • 兼容性处理:
    当反序列化旧版本的对象时,如果新版本的类中删除了某些字段或方法,Java 虚拟机会忽略这些字段或方法,而不会引发异常。
    这种处理方式允许在一定程度上保持不同版本的类的兼容性,使得应用程序在进行升级时更加灵活。

总体而言,serialVersionUID 是一个重要的概念,用于确保序列化和反序列化过程中类的版本兼容性,同时提供了灵活的手动生成方式,使开发人员能够更好地控制类的版本信息。

2. Demo

为了更加方便的显示serialVersionUID的作用,可看下方的例子

原本Entity中有一个实体类,实现了Serializable 类

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("test_user")
public class User implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private int id;private String username;private String password;// 其他字段...}

通过序列化User的对象,并再次反序列化读取对象:

import java.io.*;public class SerializationDemo {// 序列化对象public static void serializeUser(User user, String filename) throws IOException {try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename))) {out.writeObject(user);}}// 反序列化读取对象public static User deserializeUser(String filename) throws IOException, ClassNotFoundException {try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename))) {return (User) in.readObject();}}public static void main(String[] args) throws IOException, ClassNotFoundException {// 创建一个 User 对象并序列化保存User user = new User(123,"manong", "123");serializeUser(user, "user.ser");// 反序列化读取 Person 对象User deserializedPerson = deserializeUser("user.ser");System.out.println("Deserialized User: " + deserializedPerson);}
}

执行得到的结果为:Deserialized User: User(id=123, username=manong, password=123)

截图如下:

在这里插入图片描述


如果在此时修改版本(假设开发者不知道其版本),并且增加属性:

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("test_user")
public class User implements Serializable {// 修改位置private static final long serialVersionUID = 2L;@TableId(value = "id", type = IdType.AUTO)private int id;private String username;private String password;// 其他字段...private String ceshi;}

对应反序列化改为如下:

    public static void main(String[] args) throws IOException, ClassNotFoundException {// 创建一个 User 对象并序列化保存
//        User user = new User(123,"manong", "123");
//        serializeUser(user, "user.ser");try {// 反序列化读取 Person 对象User deserializedPerson = deserializeUser("user.ser");System.out.println("Deserialized User: " + deserializedPerson);}catch (IOException | ClassNotFoundException e) {System.err.println("Error deserializing: " + e.getMessage());}}

根绝提示bug,也可看出不匹配:

Error deserializing: com.example.demo.entity.User; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2

截图如下:

在这里插入图片描述

这篇关于详解Java中的serialVersionUID概念以及作用(附上Demo)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/586793

相关文章

详解Vue如何使用xlsx库导出Excel文件

《详解Vue如何使用xlsx库导出Excel文件》第三方库xlsx提供了强大的功能来处理Excel文件,它可以简化导出Excel文件这个过程,本文将为大家详细介绍一下它的具体使用,需要的小伙伴可以了解... 目录1. 安装依赖2. 创建vue组件3. 解释代码在Vue.js项目中导出Excel文件,使用第三

SQL注入漏洞扫描之sqlmap详解

《SQL注入漏洞扫描之sqlmap详解》SQLMap是一款自动执行SQL注入的审计工具,支持多种SQL注入技术,包括布尔型盲注、时间型盲注、报错型注入、联合查询注入和堆叠查询注入... 目录what支持类型how---less-1为例1.检测网站是否存在sql注入漏洞的注入点2.列举可用数据库3.列举数据库

Linux之软件包管理器yum详解

《Linux之软件包管理器yum详解》文章介绍了现代类Unix操作系统中软件包管理和包存储库的工作原理,以及如何使用包管理器如yum来安装、更新和卸载软件,文章还介绍了如何配置yum源,更新系统软件包... 目录软件包yumyum语法yum常用命令yum源配置文件介绍更新yum源查看已经安装软件的方法总结软

Java实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学