转载自https://github.com/Snailclimb/JavaGuide (添加小部分笔记)感谢作者!
什么是序列化?什么是反序列化#
当需要持久化Java对象,比如将Java对象保存在文件中、或者在网络中传输Java对象,这些场景都需要用到序列化
即:
- 序列化:将数据结构/对象,转换成二进制字节流
- 反序列化:将在序列化过程中所生成的二进制字节流,转换成数据结构或者对象的过程
对于Java,序列化的是对象(Object),也就是实例化后的类(Class)
序列化的目的,是通过网络传输对象,或者说是将对象存储到文件系统、数据库、内存中,如图:

实际场景#
- 对象在进行网络传输(比如远程方法调用 RPC 的时候)之前需要先被序列化,接收到序列化的对象之后需要再进行反序列化;
- 将对象存储到文件中的时候需要进行序列化,将对象从文件中读取出来需要进行反序列化。
- 将对象存储到缓存数据库(如 Redis)时需要用到序列化,将对象从缓存数据库中读取出来需要反序列化
序列化协议对于TCP/IP 4层模型的哪一层#
4层包括,网络接口层,网络层,传输层,应用层
如下图所示:
OSI七层协议模型中,表示层就是对应用层的用户数据,进行处理转换成二进制流;反过来的话,就是将二进制流转换成应用层的用户数据,即序列化和反序列化,
因为,OSI 七层协议模型中的应用层、表示层和会话层对应的都是 TCP/IP 四层模型中的应用层,所以序列化协议属于 TCP/IP 协议应用层的一部分
常见序列化协议对比#
kryo 英音 [k’rɪəʊ] ,除了JDK自带的序列化,还有hessian、kryo、protostuff
JDK自带的序列化,只需要实现java.io.Serializable接口即可
@AllArgsConstructor @NoArgsConstructor @Getter @Builder @ToString public class RpcRequest implements Serializable { private static final long serialVersionUID = 1905122041950251207L; private String requestId; private String interfaceName; private String methodName; private Object[] parameters; private Class<?>[] paramTypes; private RpcMessageTypeEnum rpcMessageTypeEnum; }serialVersionUID用于版本控制,会被写入二进制序列,反序列化如果发现和当前类不一致则会抛出InvalidClassException异常。一般不使用JDK自带序列化,1 不支持跨语言调用 2 性能差,序列化之后字节数组体积过大
Kryo 由于变长存储特性并使用了字节码生成机制,拥有较高的运行速度和较小字节码体积,代码:




