序列化与反序列化

posts/%E5%BA%8F%E5%88%97%E5%8C%96%E4%B8%8E%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96

序列化(serialization)在计算机科学的资料处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。依照序列化格式重新获取字节的结果时,可以利用它来产生与原始对象相同语义的副本。对于许多对象,像是使用大量引用的复杂对象,这种序列化重建的过程并不容易。面向对象中的对象序列化,并不概括之前原始对象所关系的函数。这种过程也称为对象编组(marshalling)。从一系列字节提取数据结构的反向操作,是反序列化(也称为解编组、deserialization、unmarshalling)。Wikipedia

序列化定义

序列化:把对象转化为可传输的字节序列过程称为序列化。

反序列化:把字节序列还原为对象的过程称为反序列化。

为什么要序列化?

序列化最终的目的是为了对象可以跨平台存储,和进行网络传输。而我们进行跨平台存储和网络传输的方式就是 IO,而我们的 IO 支持的数据格式就是字节数组。

因为我们单方面的只把对象转成字节数组还不行,因为没有规则的字节数组我们是没办法把对象的本来面目还原回来的,所以我们必须在把对象转成字节数组的时候就制定一种规则(序列化),那么我们从 IO 流里面读出数据的时候再以这种规则把对象还原回来(反序列化)。

什么情况下需要序列化

凡是需要进行“跨平台存储”和”网络传输”的数据,都需要进行序列化。

本质上存储和网络传输 都需要经过 把一个对象状态保存成一种跨平台识别的字节格式,然后其他的平台才可以通过字节信息解析还原对象信息。

序列化的方式

序列化只是一种拆装组装对象的规则,那么这种规则肯定也可能有多种多样,比如现在常见的序列化方式有:

  • JDK(不支持跨语言)
  • JSON
  • XML
  • Hessian
  • Kryo(不支持跨语言)
  • Thrift
  • Protostuff
  • FST(不支持跨语言)

序列化技术选型的几个关键点

  • 协议是否支持跨平台
  • 序列化的速度
  • 序列化出来的大小

Java 实现序列化

  1. 实现 Serializable 接口
  2. 把 User 对象设置值后写入文件
  3. 再把从文件读取出来的转换为对象

Java 序列化中常见的问题

  • static 属性不能被序列化
  • transient 属性不会被序列化
  • 序列化版本号 serialVersionUID 必须定义
    1. 对象属性序列化版本号不同进行序列化和反序列化版本号不同会导致错误
    2. 对象新增属性,但是版本号相同也可以反序列化成功
    3. 对象新增属性,但是版本号是使用的 JDK 生成序列化版本号,正反序列化会导致错误(版本号不同)
  • 父类、子类序列化问题
    1. 父类没有实现序列化,子类实现序列化 最后执行结果,父类属性未被序列化
    2. 父类实现序列化,子类不实现序列化 最后执行结果,子类属性序列化正常

参考链接