美文网首页
序列化版本号(serialVersionUID)是做什么用的

序列化版本号(serialVersionUID)是做什么用的

作者: 白花蛇草可乐 | 来源:发表于2019-09-28 16:17 被阅读0次

    1、为什么要序列化

    一些场景下需要把对象转变成字节序列

    • 保存到存储介质上(磁盘等)
    • 用于网络传输

    一个很常见的应用是dubbo的RPC调用,如果参数是一个bean,那么远程调用的时候必然需要传递参数对象,这时候就必须将转变为字节序列(序列化)然后通过网络传输

    2、序列化版本号的用处

    在 序列化存储/反序列化读取 或者是 序列化传输/反序列化接收 时,JVM 会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。

    在对实体类进行不影响业务流程的升级时,比如只追加了一个附加信息字段,可以不改变序列化版本号,来实现新旧实体类的兼容性(接收方的类里没有的字段被舍弃;多出来的字段赋初始值)。

    3、如何设定版本号

    1. 手动控制版本号
    private static final long serialVersionUID = 1L;
    

    实体类升级以后,可以手动控制版本号升级与否。

    1. 让IDE根据类名、接口名、成员方法及属性等来自动生成一个64位的哈希字段
    private static final long serialVersionUID = XXXL;
    

    大部分IDE都提供了自动生成这个哈希数的功能(对于实现了Serializable接口的类都有提示)。

    1. 不显示定义 serialVersionUID 。

    在这种情况下 jvm 会根据类的内容自动生成 serialVersionUID,如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID值会发生变化。

    而且类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,也有可能会导致不同的serialVersionUID。

    4、自己试验序列化、反序列化

    想学习序列化相关知识,自己做试验时,一种方法是可以简单地使用dubbo的远程调用;

    另外也可以像下面这样做对象的保存和读取

    
        public void saveObject() {
            try {
                FileOutputStream fos = new FileOutputStream(new File("FileFullpath&Name"));
                ObjectOutputStream os = new ObjectOutputStream(fos);
                SerializableDemo s = new SerializableDemo();
     
                os.writeObject(s);
                os.flush();
                os.close();
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        public void readObject() {
            try {
                FileInputStream fis = new FileInputStream(new File("FileFullpath&Name"));
                ObjectInputStream ois = new ObjectInputStream(fis);
     
                SerializableDemo s2 = (SerializableDemo) ois.readObject();
                System.out.println(s2.getB());
     
                ois.close();
     
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
    

    5、IDEA中如何自动生成serialVersionUID

    与Eclipse不同,IDEA并没有提供自动生成serialVersionUID的功能,可以通过安装 GenerateSerialVersionUID 插件来解决这个问题。

    6、Transient 关键字

    Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值。

    除了使用 Transient 关键字以外,还可以将不需要被序列化的字段抽取出来放到父类中,子类实现 Serializable 接口,父类不实现,根据父类序列化规则,父类的字段数据将不被序列化。

    7、序列化的对象范围

    在有些情况下,要注意一个容易混淆的问题:序列化针对的是“对象”,类的成员变量(static)是不会被序列化保存或者传输的,毕竟一个存在堆内存,一个存在方法区。

    相关文章

      网友评论

          本文标题:序列化版本号(serialVersionUID)是做什么用的

          本文链接:https://www.haomeiwen.com/subject/pgweuctx.html