序列化和反序列化
序列化: 将数据对象转换为二进制流的过程称为对象的序列化。
反序列化: 将二进制流恢复为数据对象的过程称为反序列化。
序列化的目的:进行数据持久化和网络传输。
常见使用场景:RPC框架的数据传输
序列化的三种方式
1、Java原生序列化
实现Serializable接口,这个接口非常特殊,没有任何方法,只起标识作用。
这种方式兼容性最好,但不支持跨语言,而且性能一般。
实现Serializable接口,建议设置serialVersionUID字段值,如果不设置,那么每次运行时,编译器会根据类的内部实现,包括类名、接口名、方法和属性等来自动生成serialVersionUID。如果类的源代码有修改,那么重新编译后serialVersionUID的取值可能发送变化。因此实现Serializable一定要显示的定义serialVersionUID属性值。
注意:Java反序列化时不会调用类的无参构造方法,而是调用native方法将成员变量赋值为对应类型的初始值。
2、Hessian序列化
Hession序列化是一种支持动态类型、跨语言、基于对象传输的网络协议。Java对象序列化二进制流可以被其他语言反序列化。
特点:
- 自描述序列化类型。不依赖外部描述文件和接口定义,用一个字节表示常用基础类型,极大缩短二进制流。
- 语言无关,支持脚本语言。
- 协议简单,比Java原生序列化高效。
3、JSON序列化
JSON是一种轻量级的数据交换格式。JSON序列化就是将数据对象转换成JSON字符串。在序列化过程中抛弃了类型信息,所以反序列化时只有提供类型信息才能准确地反序列化。
序列化通常会通过网络传输对象,二对象中往往有敏感数据,所以序列化常常成为黑客的攻击点,攻击者巧妙地利用反序列化过程构造恶意代码,使得程序在反序列化地过程中执行任意代码。
补充
如果有些对象的敏感属性不需要进行序列化传输,可以加Transient关键字,避免把此属性信息转换为序列化的二进制流。