当前位置 主页 > 网站技术 > 代码类 >

    java类中serialVersionUID的作用及其使用

    栏目:代码类 时间:2019-12-04 15:10

    实现Serializable接口的目的是为类可持久化,比如在网络传输或本地存储,为系统的分布和异构部署提供先决条件。若没有序列化,现在我们所熟悉的远程调用,对象数据库都不可能存在,

    serialVersionUID适用于java序列化机制。简单来说,JAVA序列化的机制是通过判断类的serialVersionUID来验证的版本一致的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID进行比较。如果相同说明是一致的,可以进行反序列化,否则会出现反序列化版本一致的异常,即是InvalidCastException。
    具体序列化的过程是这样的:序列化操作时会把系统当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会自动检测文件中的serialVersionUID,判断它是否与当前类中的serialVersionUID一致。如果一致说明序列化文件的版本与当前类的版本是一样的,可以反序列化成功,否则就失败;

    serialVersionUID有两种显示的生成方式:

    一是默认的1L,比如:private static final long serialVersionUID = 1L;       

    二是根据包名,类名,继承关系,非私有的方法和属性,以及参数,返回值等诸多因子计算得出的,极度复杂生成的一个64位的哈希字段。基本上计算出来的这个值是唯一的。比如:private static final long  serialVersionUID = xxxxL;
    注意:显示声明serialVersionUID可以避免对象不一致,

    当一个类实现类Serializable接口,如果没有显示定义serialVersionUIDEclipse会自动给出相应的提醒;面对这种情况,我们只需要在Eclipse中点击类的warning图标,Eclipse就会自动给出两种生成方式。如果不想定义,在Eclipse的设置中也可以把它关掉的,设置如下:
    Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems

    将Serializable class without serialVersionUID的warning改成ignore即可。

    当实现java.io.Serializable接口中没有显示的定义serialVersionUID变量的时候,JAVA序列化机制会根据Class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,如果Class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释等等),就算再编译多次,serialVersionUID也不会变化的。

    如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,就需要显示的定义一个serialVersionUID,类型为long的变量。不修改这个变量值的序列化实体,都可以相互进行序列化和反序列化。

    下面用代码说明一下serialVersionUID在应用中常见的几种情况。

    (1)序列化实体类

    package com.example.demo.entity.serializable;
     
    import java.io.Serializable;
     
    public class Persion implements Serializable {
     
      private static final long serialVersionUID = 4359709211352400087L;
      public Long id;
      public String name;
      public final String userName;
     
      public Persion(Long id, String name){
        this.id = id;
        this.name = name;
        userName = "dddbbb";
      }
     
      public String toString() {
        return id.toString() + "--" + name.toString();
      }
    }
    

    (2)序列化功能:

    package com.example.demo.entity.serializable;
     
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
     
    public class SerialTest {
     
      public static void main(String[] args) {
        Persion p = new Persion(1L, "陈俊生");
        System.out.println("person Seria:" + p);
        try {
          FileOutputStream fos = new FileOutputStream("Persion.txt");
          ObjectOutputStream oos = new ObjectOutputStream(fos);
          oos.writeObject(p);
          oos.flush();
          oos.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }