序列化版本号serialVersionUID的作用_动力节点Java学院整理

序列化是Java中非常重要且常用的一个功能。它在实现网络通信、分布式存储等方面都有广泛的应用。而序列化版本号serialVersionUID则是保证序列化的兼容性和稳定性的重要手段,它用于判断序列化对象的版本是否一致,如果不一致则不能反序列化。

在Java中,每个class都有一个serialVersionUID属性,它是一个长整型数字。如果不显式指定,Java会自动生成一个serialVersionUID。当对象被序列化时,Java会将序列化对象的对象流中写入serialVersionUID,并且在反序列化时校验该数字。

serialVersionUID的作用就是当序列化一个对象时,Java会判断这个对象的serialVersionUID和本地JVM中对应的serialVersionUID是否一致。如果一致,则可以反序列化这个对象;如果不一致,则会抛出InvalidClassException异常,反序列化失败。

示例一:同一版本的序列化和反序列化

import java.io.*;

public class SerializationTest {

    private static final String FILE_PATH = "user.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        User user = new User("张三", 20);
        System.out.println("序列化前: " + user);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_PATH));
        oos.writeObject(user);
        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_PATH));
        User newUser = (User)ois.readObject();
        ois.close();
        System.out.println("序列化后: " + newUser);
    }

    private static class User implements Serializable {
        private String name;
        private int age;

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
}

执行结果如下:

序列化前: User{name='张三', age=20}
序列化后: User{name='张三', age=20}

示例二:不同版本的序列化和反序列化

import java.io.*;

public class SerializationTest {

    private static final String FILE_PATH = "user.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        User user = new User("张三", 20);
        System.out.println("序列化前: " + user);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_PATH));
        oos.writeObject(user);
        oos.close();
        // 修改User对象的属性age的类型为long
        File file = new File(FILE_PATH);
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
        byte[] bytes = new byte[(int)randomAccessFile.length()];
        randomAccessFile.readFully(bytes);
        bytes[43] = 0x4C; // 修改0x10为0x4C
        randomAccessFile.seek(0);
        randomAccessFile.write(bytes);
        randomAccessFile.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_PATH));
        User newUser = (User)ois.readObject();
        ois.close();
        System.out.println("序列化后: " + newUser);
    }

    private static class User implements Serializable {
        private static final long serialVersionUID = 1L;
        private String name;
        private long age;

        public User(String name, long age) {
            this.name = name;
            this.age = age;
        }

        // 省略 toString 方法
    }
}

执行结果如下:

序列化前: User{name='张三', age=20}
Exception in thread "main" java.io.InvalidClassException: SerializationTest$User; local class incompatible: stream classdesc serialVersionUID = 7528517758001900623, local class serialVersionUID = 1

可以看到,当User对象被成功序列化后,我们故意修改了其属性age的类型,并重新读取了文件进行反序列化,我们得到了一个InvalidClassException异常的提示,反序列化失败。

在以上两个示例中,我们可以看到serialVersionUID属性的作用。当我们使用序列化功能时,一定要注意并理解这个字段的含义,以防止在使用中产生意外的错误。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:序列化版本号serialVersionUID的作用_动力节点Java学院整理 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • jstack+jdb命令查看线程及死锁堆栈信息的实例

    欢迎阅读本文,以下是使用jstack和jdb命令查看线程及死锁堆栈信息的实例攻略。 1.什么是jstack和jdb jstack是Java开发工具包(JDK)中的一个命令行工具,可以用于在运行时查看Java虚拟机中各个线程的状态、堆栈信息以及死锁等信息。 jdb也是JDK中的一个命令行工具,是Java Debugger的缩写,可以在运行时通过命令行调试Jav…

    Java 2023年5月26日
    00
  • Android搭建本地Tomcat服务器及相关配置

    下面我将为你详细讲解如何在Android上搭建本地Tomcat服务器及相关配置的完整攻略。 准备工作 在开始搭建之前,你需要进行以下准备工作: 安装好Android Studio开发环境; 下载Tomcat服务器安装包(例如apache-tomcat-10.0.0-M9.zip)。 搭建本地Tomcat服务器 将Tomcat服务器安装包解压到一个可用的路径下…

    Java 2023年5月19日
    00
  • Java使用JDBC向MySQL数据库批次插入10W条数据(测试效率)

    Java使用JDBC向MySQL数据库批次插入10W条数据(测试效率)攻略 本文主要介绍如何使用Java和JDBC向MySQL数据库批次插入10万条数据,并且测试其效率。 环境要求 MySQL数据库 Java开发环境 JDBC驱动 实现步骤 1. 安装MySQL数据库和JDBC驱动 如果你已经安装了MySQL数据库,那么可以跳过这一步。 安装JDBC驱动有很…

    Java 2023年5月20日
    00
  • jsp实现点击help打开chm文件

    下面是jsp实现点击help打开chm文件的完整攻略。 1. 准备工作 在服务器上搭建好jsp网站,并在网站根目录下准备好help.chm文件。 2. 编写jsp页面 在需要添加帮助文档链接的jsp页面中,添加以下代码: <a href="${pageContext.request.contextPath}/help.chm"&gt…

    Java 2023年6月15日
    00
  • JWT全面解读和详细使用步骤

    JWT全面解读和详细使用步骤 什么是JWT? JWT(JSON Web Token)是用于身份验证和授权的开放标准(RFC 7519),根据规范,JWT由三部分组成:头部(header)、荷载(payload)和签名(signature)。 头部 头部包含两个元素:令牌类型(通常是JWT)和所使用的签名算法(例如HMAC SHA256或RSA)。 使用jso…

    Java 2023年5月19日
    00
  • Spring MVC中的Controller进行单元测试的实现

    在 Spring MVC 中,Controller 是处理 HTTP 请求的核心组件。为了确保 Controller 的正确性,我们需要对其进行单元测试。本文将详细讲解如何在 Spring MVC 中对 Controller 进行单元测试的实现。 1. 单元测试环境搭建 在进行单元测试之前,我们需要先搭建好测试环境。下面是一个简单的示例,演示了如何使用 JU…

    Java 2023年5月18日
    00
  • Java对象的初始化过程是什么?

    Java对象的初始化过程是指在创建对象时,为对象的属性分配内存空间并对其进行初始化的过程。具体流程如下: 为对象分配空间 在Java中,所有的对象都是在堆内存中分配空间。在使用new关键字创建对象的时候,JVM首先会检查该类是否已被加载,如果没有被加载则先加载该类,并为该对象分配所需的内存空间。 对属性进行默认初始化 在对象创建后,JVM会为对象的所有属性分…

    Java 2023年5月11日
    00
  • springboot返回modelandview页面的实例

    首先,我们需要了解什么是 Spring Boot。Spring Boot 是 Spring 家族开源的轻量级 Web 开发框架,它简化了 Spring 繁琐的配置,使开发者能够更加专注于业务逻辑的实现。 在 Spring Boot 中,我们可以通过创建一个控制器类来处理请求并返回响应,其中返回 ModelAndView 类型的对象可以用于处理页面渲染。 以下…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部