原文网址:Java中序列化接口Serializable的serialVersionUID的作用_IT利刃出鞘的博客-CSDN博客
简介
本文介绍Java中序列化接口Serializable的serialVersionUID的作用。
序列化与反序列化
含义
- 序列化:将java对象转化为字节序列。
- 反序列化:将字节序列转化为java对象。
序列化两大用途:
- 存储:将java对象序列化成字节码保存到磁盘或者Redis等,需要的时候反序列化成java对象
- 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
转载:https://blog.csdn.net/feiying0canglang/article/details/127774141