无聊小知识01.serialVersionUID的作用

news2024/9/21 15:54:39
  1. 什么是serialVersionUID

Java(TM)对象序列化规范中描述到:serialVersionUID用作Serializable类中的版本控件。如果您没有显式声明serialVersionUID,JVM将根据您的Serializable类的各个方面自动为您执行此操作。(http://docs.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html)。

  1. 对象序列化

声明对象:

package com.shamee.demo;


public class Student {

    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

创建序列化测试类:

package com.shamee.demo;

import org.junit.jupiter.api.Test;

import java.io.*;


public class ObjectIOStreamTest {

    @Test
    public void writeToStream(){
        try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("student.obj")))) {
            oos.writeObject(new Student("张三", 18));
            oos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Test
    public void readForStream(){
        try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("student.obj")))) {
            Object o = ois.readObject();
            System.out.println(o.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

运行结果:

  1. 序列化条件

  1. 实现Serializable接口

  1. 声明serialVersionUID常量。

package com.shamee.demo;

import java.io.Serializable;

public class Student implements Serializable {
    private static final long serialVersionUID = 42L;
    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

在此运行结果:

已能够正常序列化。

  1. Serializable接口

查看Serializable接口源码可以看出,该接口没有声明任何方法,是一个标识接口。实现该接口的对象均会被识别为可序列化对象。

/**
The serialization runtime associates with each serializable class a version
 * number, called a serialVersionUID, which is used during deserialization to
 * verify that the sender and receiver of a serialized object have loaded
 * classes for that object that are compatible with respect to serialization.
 * If the receiver has loaded a class for the object that has a different
 * serialVersionUID than that of the corresponding sender's class, then
 * deserialization will result in an {@link InvalidClassException}.  A
 * serializable class can declare its own serialVersionUID explicitly by
 * declaring a field named <code>"serialVersionUID"</code> that must be static,
 * final, and of type <code>long</code>:
 *
 * <PRE>
 * ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; 
If a serializable class does not explicitly declare a serialVersionUID, then
* the serialization runtime will calculate a default serialVersionUID value
* for that class based on various aspects of the class, as described in the
* Java(TM) Object Serialization Specification.   However, it is strongly
* recommended that all serializable classes explicitly declare
* serialVersionUID values, since the default serialVersionUID computation is
* highly sensitive to class details that may vary depending on compiler
* implementations, and can thus result in unexpected
* InvalidClassExceptions during deserialization.
*/

从注释中可以看出,实现该接口。需要显示声明一个serialVersionUID。用于序列化运行时与每个可序列化类关联一个版本编号,称为serialVersionUID,在反序列化过程中使用验证序列化对象的发送方和接收方是否已经加载。

如果可序列化类没有显式声明serialVersionUID,则序列化运行时将计算一个默认serialVersionUID,因为默认的serialVersionUID计算为高度敏感的类细节,可能变化取决于编译器实现,从而导致意外在反序列化期间InvalidClassException。

简单的说,就是该serialVersionUID用于标识对象序列和反序列化过程中是唯一匹配的。

  1. 自动生成的serialVersionUID问题

自动生成的serialVersionUID可能会导致序列化和反序列化中导致异常。具体实验步骤:

  1. 声明student类,实现Serializable接口,不显式声明serialVersionUID

  1. 将对象进行序列化

  1. 修改student类

  1. 将student对象进行反序列化

声明student类:

package com.shamee.demo;

import java.io.Serializable;

public class Student implements Serializable {
    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

序列化:

@Test
    public void writeToStream(){
        try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("student.obj")))) {
            oos.writeObject(new Student("张三", 18));
            oos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

序列化成功:

修改student类:

package com.shamee.demo;

import java.io.Serializable;

public class Student implements Serializable {
    private String name;
    private int age;
    private int code;

    public Student() {
    }

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

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

接着反序列化:

直接报错,从报错信息可以看出:serialVersionUID自动生成取决于class类的字节码。因为前后类的变更导致对象的serialVersionUID发生变化,导致对象在序列化和反序列化中找不到唯一匹配标识,从而导致异常。

所以需要显式声明serialVersionUID。

  1. 如何生成serialVersionUID

IDEA点击File->Editor->Inspections。搜索框搜索UID,选择Serializable class without 'serialVersionUID'右侧复选框打勾,右下角Severity选择warning,点击OK。

之后序列化类右侧会有警告标签,点击警告标签有提示Add 'serialVersionUID' field,点击即可快速生成serialVersionUID。

无聊的小知识+1!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/359627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

神经网络的基本骨架—nn.Module使用

一、pytorch官网中torch.nn的相关简介可以看到torch.nn中有许多模块&#xff1a;二、Containers模块1、MODULE&#xff08;CLASS : torch.nn.Module&#xff09;import torch.nn as nn import torch.nn.functional as Fclass Model(nn.Module):#nn.Module---所有神经网络模块的…

Find Any File for Mac,本地文件搜索工具

Find Any File for Mac是一款简单好用的本地文件搜索工具&#xff0c;可以让你在本地磁盘上搜索、查找任何文件&#xff0c;包括本地磁盘的名称、 创建或修改日期、 大小或类型和创建者代码等。更好的结果&#xff1a;它为找到的项目提供了另一种分层视图。您可以使用cmd 2切换…

Kafka 安装入门实战

1.下载Kafka 有2个下载网站都可以&#xff1a; https://www.apache.org/dyn/closer.cgi?path/kafka/3.4.0/kafka_2.13-3.4.0.tgz https://kafka.apache.org/downloads 下载完后解压缩&#xff1a; [roottest ~]# tar -xzf kafka-3.4.0-src.tgz [roottest ~]# cd kafka_2.12-…

C# String与StringBuilder 的区分

重点 1)它是比较的栈里面的值是否相等(值比较) 2)Equals它比较的是堆里面的值是否相等(引用地址值比较) 3)Object.ReferenceEquals(obj1,obj2)它是比较的是内存地址是否相等 问题描述&#xff1a; 今日提交代码时候&#xff0c;被检测工具发出修改建议。遂补充一下知识 1.什么…

【科研】一目了然单目深度估计实验评价指标

1.度量指标表概览&#xff08;自整待完善&#xff09; SI Scale-Invariant loss尺度不变损失YES像素深度损失bi-directional chamfer loss双向槽损失YESBin中心稠密损失L1 loss & LAD & LAEL1范数损失函数 把目标值与估计值的绝对差值的总和最小化 RMSE Root Mean …

从Tomcat源码中寻找request路径进行注入

前言 前面主要是通过寻找一个全局存储的request / response来进行Tomcat中间下的回显&#xff0c;但是在tomcat 7环境下并不能够获取到StandardContext对象&#xff0c;这里李三师傅在前文的基础中发现了在AbstractProtocol$ConnectionHandler#register的调用中不仅像之前的思…

【蓝桥集训】第五天——递推

作者&#xff1a;指针不指南吗 专栏&#xff1a;Acwing 蓝桥集训每日一题 &#x1f43e;或许会很慢&#xff0c;但是不可以停下来&#x1f43e; 文章目录1.砖块递推算法是一种简单的算法&#xff0c;通过已知条件&#xff0c;利用特定关系得出中间推论&#xff0c;逐步递推&…

CSS样式

CSS Css的优势&#xff1a; 内容和表现分离网页结构表现统一&#xff0c;可以实现复用样式丰富建议使用独立的html的css CSS的导入方式 第一种导入方式 &#xff1a;行内样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"U…

清洁级动物(CL)实验室设计SICOLAB

清洁级动物&#xff08;CL&#xff09;实验室设计清洁级动物&#xff08;CL&#xff09;实验室设计有哪些内容&#xff1f;工艺流程是如何&#xff1f;功能房间的划分清洁级动物实验室&#xff08;CL实验室&#xff09;是进行高洁净度动物实验的专门场所&#xff0c;需要满足一…

无水印的电脑录屏软件,推荐这3款软件,2023年新版

很多小伙伴最近喜欢在私信中询问小编&#xff0c;都已经是2023年了&#xff0c;有没有一款特别好用无水印的电脑录屏软件。当然有啦&#xff01;今天小编就应各位小伙伴的要求&#xff0c;在这里分享3款好用的无水印电脑录屏软件&#xff0c;一起来看看吧。 无水印的电脑录屏软…

2022社交平台设备风险安卓占三成,iOS 仅占一成

目录 2022年度社交平台风险分析 社交平台黑灰产作弊手段分析 社交平台如何应对&#xff1f; 随着移动互联网的发展&#xff0c;社交媒体进入“人人皆媒”时代。社交不再仅仅满足于用户即时通讯的需求&#xff0c;还承载了在线支付、内容分享等等的多元功能&#xff0c;正不断…

Rsync服务端和客户端多模块和排错

一台服务器可能有N多个文件需要同步备份, 那怎么办呢? 其实这个也很容易解决, 就是在服务器端多建几个模块, 每个模块包含不同的文件夹, 使用同样的密码文件即可实现. 如同下面的: use chroot false #不使用chroot, 其实这个应该是针对linux系统来说的.既然是默认的, …

jQuery.NiceScroll - 有史以来最好的 nicescroll 版本——在现代浏览器和移动设备上极其流畅和一致,资源使用率低(中文文档)

jQuery.NiceScroll特征依赖关系使用配置参数有史以来最好的 nicescroll 版本——在现代浏览器和移动设备上极其流畅和一致&#xff0c;资源使用率低 官网:nicescroll.areaaperta.com GitHub:github.com/inuyaksa/jquery.nicescroll CDN引入: https://www.bootcdn.cn/jquery.nic…

Flink-Table API 和 SQL(基本API、流处理的表、时间属性和窗口、聚合查询、联结查询、函数、SQL客户端、连接到外部系统)

文章目录Table API 和 SQL快速上手基本 API程序架构创建表环境创建表表的查询输出表表和流的转换流处理中的表动态表和持续查询将流转换成动态表原理用 SQL 持续查询-更新查询&追加查询将动态表转换为流(Append-only、Retract、Upsert)时间属性和窗口事件时间处理时间窗口&…

使用react hooks 封装的圆形滚动组件

相关技术 react , hooks , ts 功能描述 根据用户的触摸&#xff0c;对卡片进行一个圆形的旋转滚动。 码上掘金 引入组件好像不支持ts类型会报错&#xff0c;所以功能函数就丢到一个文件里面了 使用 引入 ScrollRotate 组件&#xff0c;在需要使用的数据列表外包裹一层&…

[Datawhale][CS224W]图机器学习(四)

目录一、回顾二、图嵌入概述2.1 补充知识——表示学习2.2 图嵌入2.3 图嵌入-基本框架 编码器——解码器2.3.1 编码器2.3.2 解码器2.3.3 执行步骤2.4 随机游走2.4.1 随机游走的方法步骤2.4.2 计算优化三、随机梯度下降3.1 SGD步骤3.2 批处理四、node2vec五、基于随机游走的图嵌入…

vivo x TiDB丨解决云服务海量数据挑战

vivo 是一家全球性的移动互联网智能终端公司&#xff0c;品牌产品包括智能手机、平板电脑、智能手表等 &#xff0c;截至 2022 年 8 月&#xff0c;已进驻 60 多个国家和地区&#xff0c;全球用户覆盖 4 亿多人。 vivo 为用户提供了在手机上备份联系人、短信、便签、书签等数据…

k8s-kubeadm部署

文章目录一、准备环境二、安装docker三、安装kubeadm&#xff0c;kubelet和kubectl四、部署容器网络五、部署UI一、准备环境 1.安装要求 在开始之前&#xff0c;部署Kubernetes集群机器需要满足以下几个条件&#xff1a; 一台或多台机器&#xff0c;操作系统 CentOS7.x-86_x6…

论文阅读:pixelNeRF: Neural Radiance Fields from One or Few Images

中文标题&#xff1a;从一或少量图像中构建神经辐射场 提出问题 NeRF效果虽然惊艳&#xff0c;但是其需要大量环绕图像以及长时间的训练。 创新点 与原始的NeRF网络不使用任何图像特征不同&#xff0c;pixelNeRF将与每个像素对齐的空间图像特征作为输入。也可以集合更多输入…

计算机网络(第三版) 胡亮 课后习题第三章答案

计算机网络&#xff08;第三版&#xff09; 胡亮 课后习题第三章答案 1、双绞线电缆有哪两种&#xff1f; 非屏蔽双绞线&#xff08;UTP&#xff09;和屏蔽双绞线(STP) 2、UTP分为几类&#xff1f; UTP安好电气性能分为8种类型&#xff1a;1类、2类、3类、4类、5类、超5类、6类…