反序列化初识01-反序列化
一、序列化与反序列化
1.什么是序列化与反序列化?
在 Java 的世界里,一切皆对象(Object)。对象存在于内存中,当程序停止运行时,内存中的对象就会消失。
想把这个对象:
保存下来(保存到文件、数据库);
传输给别人(通过网络发送到另一台服务器);
我们就需要一种机制来转换这个对象。
序列化 (Serialization):把内存中的“Java 对象”转换成“二进制字节流(byte stream)”的过程。
反序列化 (Deserialization):把“二进制字节流”恢复成“Java 对象”的过程。
2. Java 如何实现反序列化?
java.io.Serializable 接口:只有实现了这个接口的类,其对象才能被序列化。
ObjectOutputStream:负责序列化的方法。
ObjectInputStream:负责反序列化的方法。
3.常见反序列化技术
JSON (最主流):
工具:Jackson, Gson, Fastjson。
优点:文本格式,人类可读,跨语言通用(前端 JS 也能读)。
XML:
虽然老旧,但在某些传统行业(如银行接口)还在用。
Protocol Buffers (Protobuf) / Thrift:
Google 和 Facebook 开发的。
优点:二进制格式,体积极小,速度极快,适合高性能的微服务调用(RPC)。
4.反序列化底层原理
读流:
readObject()启动,校验魔数。加载类:
Class.forName(),检查serialVersionUID。分配内存:
本身:
Unsafe.allocateInstance()(不调构造)。父类:如果父类没实现
Serializable,调用父类无参构造。
数据恢复(分支路径):
路径 A(普通):反射
field.set()暴力赋值(transient字段跳过)。路径 B(危险):发现有
readObject()方法 -> 调用之-> 此时可能触发恶意代码(RCE)。
后续处理:
检查是否有
readResolve()(用于挽救单例)。
返回对象:这就得到了一个完整的 Java 对象。
5.注意点
静态变量无法序列化
transient 标识的对象成员变量不参与序列化
为什么父类没实现
Serializable时必须要有无参构造?反序列化不会执行构造方法,但它必须让所有“没有序列化能力的父类(非
Serializable)”通过无参构造方法来初始化基础状态。
序列化类的属性没有实现 Serializable 那么在序列化就会报错
二、代码实现
1.复现代码
persion.jav
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
已在FreeBuf发表 0 篇文章
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf
客服小蜜蜂(微信:freebee1024)



