目录
[Q&A] 什么是序列化与反序列化?
序列化: 把Java对象转换成字节序列,然后通过InputStream
和OutputStream
将内存中的类持久化到硬盘或者网络中传输。
反序列化: 把字节序列恢复为Java对象的过程。
[Q&A] JSON字符串 和 字节序列 区别
都是表示数据的方式。
JSON字符串:文本格式,人类可读,适合网络传输和配置文件。
字节序列:二进制格式,紧凑高效,适合网络传输和文件存储。
[Q&A] 为什么要序列化与反序列化?
对象、文件、数据,有许多不同的格式,很难统一传输和保存。序列化以后就都是 字节流了,无论原来是什么东西,都能变成一样的东西,就可以进行通用的格式传输或保存,传输结束以后,要再次使用,就进行反序列化还原,这样对象还是对象,文件还是文件。
[Q&A] 序列化应用场景
- 将内存中的类持久化到文件或数据库。
- 网络传输。
- 对象序列化可以实现分布式对象。
RMI
(Remote Method Invocation,远程调用) 要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。
RPC
(Remote Procedure Call,远程过程调用)
[Q&A] RMI 和 RPC 区别
RMI
:允许一个 Java 对象调用另一个位于不同 JVM 上的对象的方法。仅支持Java,仅在 JVM 之间工作。
RPC
:允许一个程序调用另一个位于不同计算机上的子程序或过程,就像调用本地子程一样。支持多种编程语言,如 C/C++、Python、Go 等。
[Q&A] 序列化特点
- 递归保存:java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。
[Q&A] 哪些类可以序列化?
- 数组
- 枚举
- 实现
Serializable
接口或Externalizable
接口
Serializable 和 Externalizable区别?
[Q&A] 什么是serialVersionUID
[Q&A] 如何禁止某个字段的持久化
[Q&A] Java中常用的序列化框架
- java原生:java.io.Serializable
- gson:谷歌开源
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
- fastjson:阿里巴巴开源
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
- jackson:Tatu Saloranta 创建的。Tatu Saloranta 是一位经验丰富的软件工程师
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
[Q&A] java原生序列化和反序列化执行路径
writeObject
writeObject0
:判断类是否为自定义类writeOrdinaryObject
:区分Serializable
和Externalizable
writeSerialData
:序列化fields
invokeWriteObject
:反射调用类自己的序列化策略
如果被序列化的类中定义了writeObject
和readObject
方法,虚拟机会试图调用对象类里的writeObject
和readObject
方法,进行用户自定义的序列化和反序列化。
如果被序列化的类没有定义这2个方法,则默认调用是ObjectOutputStream.defaultWriteObject
和ObjectInputStream.defaultReadObject
方法来执行序列化和反序列化。
ArrayList<String> list = new ArrayList<>();
list.add("Alice");
list.add("Bob");
list.add("Charlie");
# 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.ser"))) {
oos.writeObject(list);
} catch (Exception e) {
e.printStackTrace();
}