初识Java的序列化和反序列化
序列化和反序列化概念
- Java 序列化是指把 Java 对象转换为字节序列的过程便于保存在内存、文件、数据库中,如将 Java 对象转为一个 bin 文件或将一个 Java 对象转为一个 JSON 字符串,都是为了保存和不同服务之间对象的传输。
- Java 反序列化是指把字节序列恢复为 Java 对象的过程。
序列化的应用场景
- 序列化是指把一个 Java 对象变成二进制内容,本质上就是一个
byte[]数组。 - 为什么要把 Java 对象序列化呢?因为序列化后可以把
byte[]保存到文件中,或者把byte[]通过网络传输到远程,这样,就相当于把Java对象存储到文件或者通过网络传输出去了。 - 有序列化,就有反序列化,即把一个二进制内容(也就是
byte[]数组)变回Java对象。有了反序列化,保存到文件中的byte[]数组又可以“变回”Java对象,或者从网络上读取byte[]并把它“变回”Java 对象。
序列化的过程

对象的序列化
一个对象要能序列化,必须实现一个特殊 java.io.Serializable接口,该接口是空接口,无需要实现的相应方法,它的定义如下:
1 | public interface Serializable { |
下面以序列化 Use 类为例:
1 | public class User implements Serializable { |
1 | public class SerializeTest { |
运行以上代码会生成 user.ser文件。
对象的反序列化
和 ObjectOutputStream相反,ObjectInputStream负责从一个字节流读取 Java对象。
1 | public class UnserializeTest { |

反序列化的核心原理
Java 序列化数据通常以 AC ED 00 05开头,其中 AC ED表示是 Java序列化文件的专属标识,00 05则表示序列化协议的版本号。


反序列化过程中的关键步骤:
- 类加载与校验:JVM 尝试加载字节流中指定的类
- 对象实例化:创建对象实例但不调用构造函数
- 属性恢复:按顺序恢复对象的属性值
- 自定义反序列化:如果类实现了自定义的
readObject()方法,则调用此方法
以下为演示过程:
序列化机制在还原对象时,会自动触发对象内部的特殊方法(如 readObject),而攻击者可通过构造恶意的序列化数据,让这些方法执行非预期的危险操作。
在被反序列化的类中定义私有的 readObject方法有且仅有一个参数,即 ObjectInputStream。
1 | public class User implements Serializable { |
先对 User 类序列化获得相应的序列化二进制文件,接着进行反序列化。
1 | public class UnserializeTest { |
运行即可执行被反序列化类中的 readObject()方法。

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 X1ongSec!


