什么是序列化

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

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

为什么要序列化

序列化的最终目的是为了对象可以跨平台存储、能够进行网络传输。进行跨平台存储和进行网络传输的方式就是IO,而IO所支持的数据格式就是字节数组。
但单纯的转化为字节数组是没有意义的,因为传输的双方并不能进行反序列化,如果想要接收方能够将接收到的字节数组转换为对象,就需要两方互相沟通好一种规则,根据这种协议进行还原。

什么时候需要序列化

当需要跨平台存储、网络传输时,我们就需要序列化。

序列化的方式

序列化只是一种拆装组装对象的规则,这种规则肯定是多种多样的。现在有如下常见的序列化方式
JDK(不支持跨语言)、JSON、XML、Hessian、Kryo(不支持跨语言)、Thrift、Protostuff、FST(不支持跨语言)

如何选择合适的序列化方式

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

Java序列化中常见的问题

  • static属性不能被序列化
  • Transient属性不会被序列化
  • 序列化版本号serialVersionUID
    所有序列化的对象都会有一个版本号,这个版本号可以是自定义的,当未自定义时,就会按照对象的属性生成一个对应的版本号。
    要理解这个版本号,其实就和乐观锁中的版本号差不多,都是为了两方能够知道当前的数据是否是我们想要的。当序列化的对象因业务需求的变动而发生改变时,反序列化的一方肯定需要知情,而告知的方式就是版本号的变化。
    JDK为我们自动生成的序列化版本号是根据对象属性生成的,当对象属性有变动时,版本号就会发生改变。用户不更新软件版本就没法使用。但现在的软件都会给用户增加忽略更新的功能,所以不能使用JDK自己生成的版本号,而是需要使用我们自定义的版本号。
  • 父类子类的序列化问题
    序列化以正向递归形式进行,若父类实现了序列化,那么其子类都会被序列化;若子类实现了序列化而父类未实现序列化,那么只有子类的属性会进行序列化,而父类的属性是不会进行序列化的。