序列化版本号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日

相关文章

  • Java从服务器上获取时间动态显示在jsp页面实现思路

    获取服务器上的时间并动态地显示在 JSP 页面上可以通过以下步骤来实现: 在 JSP 页面上引入 Java 提供的日期处理类库 java.util.Date 通过 Java 代码获取当前的时间并将其转化为字符串格式 在 JSP 页面上使用 JavaScript 定时刷新页面内容,动态显示时间 以下是具体的实现步骤和示例代码: 引入 Date 类库 在 JSP…

    Java 2023年5月20日
    00
  • asp.net内置对象 Response对象使用介绍

    ASP.NET是一个基于.NET Framework的Web应用程序开发框架。在ASP.NET的开发过程中,Response对象是一个非常重要的内置对象,它提供了很多方法和属性来管理HTTP响应。本文将介绍如何利用Response对象来控制HTTP响应的内容和属性。 Response对象的作用 在ASP.NET的Web应用程序中,Response对象用于向客…

    Java 2023年5月19日
    00
  • spring-boot-plus V1.4.0发布 集成用户角色权限部门管理(推荐)

    Spring Boot Plus V1.4.0发布 Spring Boot Plus是一个基于SpringBoot的项目快速开发脚手架,版本 V1.4.0 提供了用户角色权限部门管理的集成,方便用户快速搭建管理后台。 安装 首先,我们需要安装Java和Maven,参考:- Java 安装教程- Maven 安装教程 Spring Boot Plus 是通过M…

    Java 2023年5月20日
    00
  • Java由浅入深细数数组的操作上

    Java数组操作完整攻略 一、数组概述 Java数组是一种包含固定数量元素的数据结构,这些元素属于同一种数据类型。 Java数组由以下几个基本点组成: 数组声明 数组的创建 数组的初始化 数组的访问 数组的遍历 二、数组的声明 Java中数组的声明包含两个重要的部分,第一部分是数组的类型,第二部分是数组的名字。如下所示: int[] arr; //第一种声明…

    Java 2023年5月26日
    00
  • mvc 、bootstrap 结合分布式图简单实现分页

    MVC、Bootstrap结合分布式图简单实现分页攻略 本文将详细讲解如何使用MVC、Bootstrap和分布式图来实现分页功能。我们将使用SpringMVC作为MVC框架,Bootstrap作为前端框架,分布式图作为数据可视化工具。本文将提供两个示例说明,以帮助您更好地理解如何实现分页功能。 1. 创建SpringMVC项目 首先,我们需要创建一个Spri…

    Java 2023年5月18日
    00
  • Java计算器核心算法代码实现

    请听我详细讲解“Java计算器核心算法代码实现”的完整攻略。 概述 在实现一个Java计算器时,核心的算法是计算表达式的值。本攻略将详细介绍如何使用栈和逆波兰表达式来实现计算器的核心算法。 栈的使用 栈是一种后进先出(LIFO)的数据结构。因为计算器中涉及到的算法通常都需要借助栈来实现。我们通过栈来计算表达式的值。 在Java中,Stack类是一个非常基础的…

    Java 2023年5月18日
    00
  • Spring Data JPA 注解Entity关联关系使用详解

    Spring Data JPA 是 Spring Data 项目中处理 JPA 持久层的一种方法,它提供了很多注解和工具来简化 JPA 操作,其中 Entity 关联关系是 JPA 中的核心概念之一。本文将介绍 Spring Data JPA 中 Entity 关联关系的使用方法,主要包括关联关系的种类、注解的使用和案例演示。 关联关系种类 在 JPA 中,…

    Java 2023年6月3日
    00
  • java实现Floyd算法

    Java实现Floyd算法 Floyd算法是解决图中最短路问题的一种经典算法,它可以求出图中任意两点之间的最短路径。下面我们将详细讲解如何使用Java实现Floyd算法。 算法思路 Floyd算法是一种动态规划算法,它通过逐步优化不同的路径来求取图中任意两点之间的最短路径。 我们可以用一个二维数组dis来存储图中任意两点之间的距离。具体地,dis[i][j]…

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