摘要
本文介绍Java序列化和反序列化,并模拟IDEA中不显式指定序列化ID时的报错场景。
认识序列化和反序列化
序列化:把JVM内存中的对象转换成字节序列(字节流、文件流、网络流、JSON、XML),便于持久化、网络传输和缓存。
反序列化:把字节序列重新还原成内存中的对象。
为什么需要序列化和反序列化?
- 缓存和持久化:将对象存储到文件或数据库中,便于长期保存。
- 深拷贝:先序列化再反序列化,可快速得到一个全新对象。
- 网络通信:在分布式系统中传输对象数据,支持远程调用和实时交互。
- 跨平台传输:将对象转换为通用格式(如JSON、XML),实现不同平台或语言间的数据交换。
实体类必须实现Serializable吗?
| 是的 | 仅用Java原生ObjectOutputStream写磁盘/网络传输 |
|---|---|
| 放入Redis、Kafka、MQ且采用JDK默认序列化 | |
| 不是 | 子类继承父类,父子其中一个实现Serializable即可 |
| 使用Spring、MyBatis、JPA等仅做ORM映射 | |
| 放入Redis、Kafka、MQ且采用JSON |
IDEA开启SerialVersionUID智能生成实现Serializable,最好显式写明SerialVersionUID打开IDEA设置搜索serialversion,勾选以下选项
开启后,实现Serializable时会出现警告,按提示即生成
生成成功
模拟序列化反序列化失败的场景
1)定义一个对象
package org.coffeebeans;
import java.io.Serializable;
publicclass User implements Serializable {
//模拟显式指定序列化版本号
// private static final long serialVersionUID = 1L;
// 模拟结构变更
private int age;
private String name;
public String getName() {
return name;
}
public User(String name) {
this.name = name;
}
}
2)序列化和反序列化测试
package org.coffeebeans;
import java.io.*;
public class SerializeTest {
public static void main(String[] args) {
serialize();
deserialize();
}
static void serialize() {
User user = new User("测试");
try (ObjectOutputStream out = new ObjectOutputStream(newFileOutputStream("User.txt"))) {
out.writeObject(user);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("序列化完成");
/*
生成二进制文件User.txt:
sr org.coffeebeans.User6聳帡f狦 L namet Ljava/lang/String;xpt 娴嬭瘯
*/
}
static void deserialize() {
try (ObjectInputStream out = new ObjectInputStream(new FileInputStream("User.txt"))) {
User user = (User) out.readObject(); // 反序列化
System.out.println("反序列化成功: " + user.getName());
} catch (Exception e) {
e.printStackTrace();
}
/*
没有显式指定序列化ID,序列化后,变更User结构,直接反序列化,结构报错:
java.io.InvalidClassException: org.coffeebeans.User; local class incompatible:
stream classdesc serialVersionUID = 3945881762699586119,
local class serialVersionUID = -7390599950155181816
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1843)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1713)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2000)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at org.coffeebeans.SerializeTest.deserialize(SerializeTest.java:24)
at org.coffeebeans.SerializeTest.main(SerializeTest.java:9)
*/
}
}
总结
以上我们了解了Java序列化和反序列化,并开启了IDEA的序列化ID智能生成器,同时模拟了IDEA中不显式指定序列化ID时的报错场景。
关注公众号:咖啡Beans
在这里,我们专注于软件技术的交流与成长,分享开发心得与笔记,涵盖编程、AI、资讯、面试等多个领域。无论是前沿科技的探索,还是实用技巧的总结,我们都致力于为大家呈现有价值的内容。期待与你共同进步,开启技术之旅。