Java中序列化接口Serializable的serialVersionUID的作用

原文网址:Java中序列化接口Serializable的serialVersionUID的作用_IT利刃出鞘的博客-CSDN博客

简介

        本文介绍Java中序列化接口Serializable的serialVersionUID的作用。

序列化与反序列化

含义

  • 序列化:将java对象转化为字节序列。
  • 反序列化:将字节序列转化为java对象。

序列化两大用途:

  1. 存储:将java对象序列化成字节码保存到磁盘或者Redis等,需要的时候反序列化成java对象
  2. RPC:将java对象序列化成字节码在网络上传输

serialVersionUID

        序列化时把serialVersionUID 写入文件中,反序列化时检测文件中的serialVersionUID 和类的serialVersionUID 是否一样。如果一样可以则可以反序列化,否则会抛异常,反序列化会失败。

        如果没有指定serialVersionUID,那么对象在被序列化的时候,JVM会根据包名、类名、变量、参数、返回值等自动生成serialVersionUID,如果我们修改了对象的成员,那么这个serialVersionUID就会发生变化。当对象被反序列化的时候,这两个值不相等,就会报错。

        所以需要手动指定serialVersionUID:

private static final long serialVersionUID = 1L;

实例

例1:正常用法

Entity

package com.knife.entity;

import lombok.Data;

import java.io.Serializable;

@Data
public class User implements Serializable {
    private static final long serialVersionUID = 333225L;

    private Long id;

    private String userName;

}

Controller

package com.knife.controller;

import com.knife.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;

@RestController
public class TestController {

    @GetMapping("serialize")
    public String serialize() {
        User user = new User();
        user.setId(2L);
        user.setUserName("Tony");

        try {
            FileOutputStream fos = new FileOutputStream("User.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(user);
            oos.flush();
            oos.close();
        } catch (IOException e) {
            e.printStackTrace();
            return e.getMessage();
        }

        return "serialize success";
    }

    @GetMapping("deSerialize")
    public String deSerialize() {
        User user;
        try {
            FileInputStream fis = new FileInputStream("User.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            user = (User) ois.readObject();
            ois.close();
            System.out.println(user.toString());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return e.getMessage();
        }

        return "deSerialize success";
    }
}

测试

1.序列化

此时后端生成了User.txt

2.反序列化

后端输出

User(id=2, userName=Tony)

例2:未指定serialVersionUID时报错

        Entity中去掉serialVersionUID,序列化,然后修改Entity,添加一个字段,然后反序列化,此时会报错。

Entity中去掉serialVersionUID,如下:

package com.knife.entity;

import lombok.Data;

import java.io.Serializable;

@Data
public class User implements Serializable {
    private Long id;

    private String userName;

}

1. 序列化  

此时生成User.txt

2.增加字段并重启应用

Entity添加一个字段

package com.knife.entity;

import lombok.Data;

import java.io.Serializable;

@Data
public class User implements Serializable {
    private Long id;

    private String userName;
    
    private String age;

}

重启应用

3.反序列化

可以发现,反序列化报错。原因是:本地类不兼容:流的serialVersionUID = 3441701338525863619,本地类的serialVersionUID = 2482712775234331218

猜你喜欢

转载自blog.csdn.net/feiying0canglang/article/details/127774141