private static final Long serialVersionUID= 1L详解

这篇具有很好参考价值的文章主要介绍了private static final Long serialVersionUID= 1L详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

我们知道在对数据进行传输时,需要将其进行序列化,在Java中实现序列化的方式也很简单,可以直接通过实现Serializable接口。但是我们经常也会看到下面接这一行代码,

private static final Long serialVersionUID= 1L;

这段代码到底有什么用呢? 为什么有些代码写了它,有些代码没写?

一、案例代码1

首先我们看这一段代码

public class Person implements Serializable {

    private String name;

    private Integer age;

    public Person(){}

    public Person(String name, Integer age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class IOTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        out();
        //in();
    }

    public static void out() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream("C:\\Users\\Lenovo\\Desktop\\java练习\\src\\main\\resources\\Person.txt"));
        Person person = new Person("张三",18);

        oos.writeObject(person);
        oos.close();
    }

    public static void in() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream("C:\\Users\\Lenovo\\Desktop\\java练习\\src\\main\\resources\\Person.txt")
        );
        Object object = ois.readObject();
        System.out.println(object);
    }
}

执行该段代码,运行结果

private static final Long serialVersionUID= 1L详解

然后将out();注释掉, 执行in();

private static final Long serialVersionUID= 1L详解

如果这个时候我修改了Person类,增加sex成员变量

public class Person implements Serializable {

    private String name;

    private Integer age;
    
    private char sex;

    public Person(){}

    public Person(String name, Integer age, char sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public Person(String name, Integer age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

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

我在执行IOTest类中的in()方法(注释掉out();方法), ,发现会报错

private static final Long serialVersionUID= 1L详解

这是为什么呢?为什么只是在Person类中增加了一个char sex成员变量, 执行in()方法就会报错.

二、案例代码2

如果在以上Person类中添加

private static final long serialVersionUID = 1L;

按照案例代码1中的执行顺序运行一遍代码,(先将Person.txt文件中的内容全部删除)

private static final Long serialVersionUID= 1L详解

这是为什么呢?

三、案例代码1和案例代码2分析

这里先搞清楚java中的序列化和反序列化代表什么意思

序列化:把Java对象转换为字节序列的过程

方序列化:把字节序列恢复为Java对象的过程。

private static final Long serialVersionUID= 1L详解

这里看一下案例代码1执行所产生的的错误:invalidClassException,然后我们再看下面一行serialVersionUID有两个不同的值,仔细分析,发现这两个不同的值才是产生异常的原因。

在案例1代码中我们在Person类中没有设置serialVersionUID值。我们首先执行的是out()方法,作用就是将person对象写入(序列化)到Person.txt文件中,而在序列化的过程中Person类也会产生一个serialVersionUID值,如果Person类中没有定义serialVersionUID值,则系统会自动生成一个值,就是第一个5428155211170925772,会存入到Person.txt文件中,然后我们在Person类中增加了一个sex成员变量,注释掉out()方法,执行in()方法,相当于一个反序列化的过程,这个时候会报错,是因为在Person类由于被增加了一个sex成员变量,导致系统生成的serialVersionUID改变了,变成了-1544469845932994986,而我们存入到Person.txt文件中的person对象的serialVersionUID却是5428155211170925772所以系统就判定这两个Person类不是同一个,就会导致invalidClassException异常。

案例2代码中我们规定了Person类中private static final long serialVersionUID = 1L的值,这就保证了无论Person类再怎么变,serialVersionUID都是一个固定的值,不再是系统生成的,这就能够避免Person类增加或者减少成员变量都不会导致serialVersionUID改变。

这是java源码中的一段话

如果可序列化类没有显式声明serialVersionUID,那么序列化运行时将根据类的各个方面计算该类的默认serialversion UID值,如Java对象序列化规范中所述。此规范将枚举类型的seriaVersionUID定义为0L。但是。强烈建议除枚举类型之外的所有可序列化类都显式声明serialVersionUID值,因为默认的

seriaverslon UID计算对类细节非常敏感,这些细节可能因编译器实现而有所不同。因此在反序列化过程中可能会导致意外的InvalidClassException。因此。为了保证不同java编译器实现中的serialVerslonUID值一致。可序列化类必须声明显式serialVersionUID值。此外。强烈建议显式serialVersionUID声明尽可能使用私有修饰符。因为此类声明仅适用于立即声明的类—serialVersionUID字段作为继承成员没有用处。数组类不能声明显式的serialversionUID,因此它们总是具有默认的计算值,但数组类不需要匹配serialVersion UID值。文章来源地址https://www.toymoban.com/news/detail-430924.html

到了这里,关于private static final Long serialVersionUID= 1L详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • static关键字和final关键字

    在java的中,static和final是两个必须掌握的。static和final用法多样,且在一定环境下使用,可以提高程序的运行性能,优化程序的结构。下面将依次介绍static和final。注意,某些场景下,staic和final可以联合使用

    2024年02月09日
    浏览(38)
  • junit单元测试mock私有private方法和静态static方法

    我们知道org.mockito.Mockito功能有限,不能mock 私有private、受保护的protected方法 org.powermock.api.mockito.PowerMockito更强大,支持对private和protected和static方法的mock 别忘记,首先要引入maven依赖 有如下私有方法需要mock 这时候可以利用PowerMockito的spy方法mock出方法所在的对象,然后利用

    2024年02月12日
    浏览(28)
  • 面向对象(八)-- static 与 final 关键字 的使用

    目录 1.  static 1.1  static 的概述 1.2  static 修饰的特点 1.3  static 使用时的注意事项:

    2023年04月25日
    浏览(31)
  • 学习JavaEE的日子 day13 封装 static private this 类加载机制

    理解:private是访问修饰符的一种,访问修饰符规定了访问权限. 作用: ​ 1.private修饰属性:该属性只能在类的内部使用 ​ 2.private修饰方法:该方法只能在类的内部使用 应用场景:不让让外界访问的属性和方法就用private修饰 面向对象三大特征之一: 封装,继承,多态 理解:

    2024年01月18日
    浏览(36)
  • Unable to make field private final java.lang.Class java.lang.invoke

    java版本是17 mybatis-plus 版本是3.5.1 报错内容如下:  Unable to make field private final java.lang.Class java.lang.invoke.SerializedLambda.capturingClass accessible: module java.base does not \\\"opens java.lang.invoke\\\" to unnamed module @4f6ee6e4 解决方式: idea版本是2023.1.3  shift+F4 或者 Edit configruation... 修改参数 Modify Optio

    2024年02月11日
    浏览(37)
  • Mybatisplus报错 field private final java.lang.Class java.lang.invoke.SerializedLambda.capturingClass

    Unable to make field private final java.lang.Class java.lang.invoke.SerializedLambda.capturingClass accessible: module java.base does not “opens java.lang.invoke” to unnamed module @6dc17b83 其实是Mybatisplus和Java的版本兼容出现了问题。 这个错误是因为在 Java 9 及之后的版本中,模块化系统 (Module System) 引入了访问限

    2024年02月04日
    浏览(41)
  • 【Bug】Unable to make field private final int java.time.LocalDate.year accessible

    在使用这段代码时 new Gson().toJson(result) ,会出现如下异常 gson不能使用反射,将 LocalDate , LocalDateTime 等时间类型反射调用; 请检查一下,你的项目JDK的版本是否是JDK9以上(Gson 是通过反射的方式来访问相关的属性的,而这一方式在 JDK 9 开始就已经被禁用了); 有两种解决方式: 1.使用

    2024年02月07日
    浏览(50)
  • 【Java入门】final关键字、static关键字、内部类的认识

    前言 : final是Java中的一个修饰符,用于表示某个变量、方法或者类不能被修改。final可以用于修饰类、方法和变量(局部变量,成员变量)。被final所修饰的类不能被继承,被final所修饰的方法不能被重写,被final所修饰的变量,不能被重新赋值 。 static是Java中的一

    2024年02月11日
    浏览(35)
  • 安装JDK:Unable to make field private final java.lang.String java.io.File.path accessible

    BUILD FAILED Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not “opens java.io” to unnamed module @63f6847a 解决办法:JDK改为17以下即可。例如我改为11,直接就OK了 另外经常编译项目 强烈建议大家 能配置多个编译环境。直接terminal中./gradlew assembleReleas

    2024年02月02日
    浏览(35)
  • 【Java】使用PowerMockito mock static方法/new对象/mock对象的public或private方法的简单示例

    1.1 打桩类的public static方法 测试用例中如果需要对public静态方法的打桩,针对测试类增加注解@RunWith(PowerMockRunner.class)同时针对静态方法所在的类增加注解@PrepareForTest({StaticMethod.class}),接着在测试用例调用方法之前增加 PowerMockito.mockStatic(StaticMethod.class); PowerMockito.when(StaticMet

    2024年01月24日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包