Java 序列化和反序列化详解

Java 中序列化是指将运行时的对象转换成可网络传输或存储的字节流的过程,而反序列化则是将字节流恢复成对象的过程。

序列化的应用包括持久化存储(将对象状态保存到存储设备中,以便后续读取使用)、网络传输(将对象转换成字节流,通过网络发送给另一个 JVM 实例,接收方再将字节流转回对象)、深度复制(通过序列化与反序列化可以实现对象的深复制,即创建一个新的对象,并且新对象的数据与原对象相同,但它们在内存中的地址不同)。

Java 原生方式

要使一个类的对象能够被序列化,只需要让这个类实现 Serializable 接口即可。Serializable 是一个标记接口,它没有定义任何方法。然后可以使用 ObjectOutputStream#writeObject() 方法序列化对象,以及使用 ObjectInputStream#readObject() 方法反序列化对象。

第三方方式

使用 Java 原生序列化方式序列化的对象只能被 Java 读取(反序列化),所以可以考虑先把对象转成一种通用的格式——如 JSON 字符串,然后把 JSON 字符串转成字节流进行网络传输,从而实现跨平台或者跨语言。市面上也有开源的序列化工具,比如 JSON、Xml、hessian等。

反序列化漏洞

反序列化是把数据流转成对象,如果数据流被人恶意加工过,就会存在安全隐患。在 Java 中,如果数据流的对象自己重写了 readObject() 方法,Java 会调用自己的这个 readObject() 方法,这就给了攻击者可乘之机,他们就能在自己的 readObject() 方法里写攻击代码。为了方便定制化某些类的序列化方法,Java 允许我们重写 readObject 方法。但这也为攻击者提供了机会。因此,反序列化漏洞需要引起重视。

标签:游戏攻略