Java 序列化与反序列化实战:从对象持久化到复杂结构读取
Java 序列化是将对象转换为字节序列的过程,而反序列化则是将其还原。本文通过一个完整的 Java 代码实例,演示如何序列化自定义对象、基本数据类型、List 集合以及复杂的 HashMap 嵌套结构,并展示正确的读取顺序和类型转换方法,适用于需要对象持久化存储的开发场景。
概述:理解序列化与反序列化
在 Java 开发中,序列化(Serialization)是指把 Java 对象转换为字节序列的过程,以便进行网络传输或保存到文件系统;反序列化(Deserialization)则是相反的过程,即把字节序列恢复为 Java 对象。
要实现序列化,关键在于让类实现 java.io.Serializable 接口。该接口是一个标记接口,不包含任何方法,主要作用是给 JVM 提供序列化标识。通常建议显式声明 serialVersionUID,以确保版本兼容性和唯一性。
准备条件与依赖导入
在进行序列化操作前,需确保目标类已实现 Serializable 接口,并在代码头部引入必要的 IO 流类和工具类:
ObjectOutputStream:用于将 Java 对象写入输出流。ObjectInputStream:用于从输入流中读取 Java 对象。FileOutputStream/FileInputStream:用于连接磁盘文件。
第1步:构建可序列化的自定义类 Customer
首先创建一个名为 Customer 的类,实现 Serializable 接口。该类包含 name(String)和 age(int)两个字段,并提供构造函数、Getter 方法及 toString() 重写以方便打印。
class Customer implements Serializable {
// 版本号,保证序列化前后类的兼容性
private static final long serialVersionUID = 1L;
private String name;
private int age;
public String getName() { return name; }
public int getAge() { return age; }
public Customer(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "name=" + name + ", age=" + age;
}
}
第2步:执行序列化操作(写对象至文件)
使用 ObjectOutputStream 将多种类型的数据写入 D:/objectFile.obj。注意写入顺序决定了反序列化时的读取顺序,必须严格一致。
public static void main(String[] args) {
try {
// 1. 初始化输出流
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:/objectFile.obj"));
// 2. 写入不同类型的对象
out.writeObject("你好!"); // 字符串
out.writeObject(new Date()); // 日期对象
out.writeObject(new Customer("中国人", 23)); // 自定义对象
out.writeInt(123); // 基本数据类型
// 3. 写入集合对象
List list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(new Customer("中国人", i));
}
HashMap();
hashMap.put("customer", list);
out.writeObject(hashMap); // 嵌套结构对象
// 4. 关闭流
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
第3步:执行反序列化操作(从文件读对象)
使用 ObjectInputStream 按写入时的逆序读取数据。**重要原则**:读取的类型必须与写入的类型匹配,且顺序不能错乱,否则会导致 ClassCastException 或 StreamCorruptedException。
try {
// 1. 初始化输入流
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/objectFile.obj"));
// 2. 依次读取并强转类型
String obj1 = (String) in.readObject();
System.out.println("obj1= " + obj1);
Date obj2 = (Date) in.readObject();
System.out.println("obj2= " + obj2);
Customer obj3 = (Customer) in.readObject();
System.out.println("obj3= " + obj3);
int obj4 = in.readInt();
System.out.println("obj4= " + obj4);
// 读取最后写入的 HashMap
Object obj5 = in.readObject();
HashMap
完成判断与注意事项
当控制台成功打印出 "你好!"、当前日期、Customer 信息以及 HashMap 的大小和内容时,表明序列化和反序列化操作成功完成。
- 顺序一致性:必须先写后读,且类型对应。例如先写了
writeInt,就必须用readInt,不能用readObject强制转换整数。 - 异常处理:序列化过程可能抛出
FileNotFoundException、IOException或ClassNotFoundException(反序列化时找不到类定义),需妥善捕获。 - 安全性提醒:直接反序列化不受信任来源的数据存在安全风险(如远程代码执行漏洞),生产环境中应校验数据源或使用白名单过滤。
以上就是 Java 序列化与反序列化操作实例分析的详细内容,更多关于 Java 对象持久化的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









