序列化(Serialization)和反序列化(Deserialization)是在计算机科学中常用的两个概念,用于在不同的环境中存储和传输对象。下面分别从定义、作用、Java 中的实现以及 Python 中的实现等方面进行详细介绍。

定义

  • 序列化:将对象转换为字节流的过程称为序列化。这个字节流包含了对象的数据和相关的元信息,使得对象可以被存储到文件、数据库或者通过网络进行传输。
  • 反序列化:将字节流重新转换为对象的过程称为反序列化。通过反序列化,可以将之前序列化得到的字节流恢复成原来的对象。

作用

  • 数据持久化:可以将对象的状态保存到文件或数据库中,以便在程序下次启动时恢复对象的状态。
  • 网络传输:在网络通信中,需要将对象转换为字节流进行传输,接收方再将字节流反序列化为对象。
  • 分布式系统:在分布式系统中,不同节点之间需要交换对象信息,序列化和反序列化可以实现对象在不同节点之间的传输。

Java 中的实现

序列化

在 Java 中,要实现对象的序列化,需要让类实现 java.io.Serializable 接口,该接口是一个标记接口,没有任何方法。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

// 实现 Serializable 接口
class Person implements Serializable {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}

public class SerializationExample {
public static void main(String[] args) {
Person person = new Person("Alice", 20);

try (FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
// 序列化对象
out.writeObject(person);
System.out.println("对象已序列化到 person.ser 文件");
} catch (IOException e) {
e.printStackTrace();
}
}
}

反序列化

反序列化时,使用 ObjectInputStream 从文件中读取字节流并将其转换为对象。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeserializationExample {
public static void main(String[] args) {
try (FileInputStream fileIn = new FileInputStream("person.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)) {
// 反序列化对象
Person person = (Person) in.readObject();
System.out.println("姓名: " + person.getName());
System.out.println("年龄: " + person.getAge());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}

Python 中的实现

在 Python 中,可以使用 pickle 模块来实现对象的序列化和反序列化。

序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
import pickle

class Person:
def __init__(self, name, age):
self.name = name
self.age = age

person = Person("Bob", 25)

# 序列化对象并保存到文件
with open('person.pkl', 'wb') as file:
pickle.dump(person, file)
print("对象已序列化到 person.pkl 文件")

反序列化

1
2
3
4
5
6
7
import pickle

# 从文件中读取字节流并反序列化对象
with open('person.pkl', 'rb') as file:
person = pickle.load(file)
print("姓名:", person.name)
print("年龄:", person.age)

注意事项

  • 版本兼容性:在进行序列化和反序列化时,要注意类的版本兼容性。如果类的结构发生了变化,可能会导致反序列化失败。
  • 安全性:反序列化过程可能存在安全风险,因为恶意的字节流可能会执行一些危险的操作。在处理来自不可信源的字节流时,要格外小心。