序列化与反序列化

序列化与反序列化

  1. 序列化:把对象转换为字节数组的过程称为对象的序列化。
  2. 反序列化:把字节序列转换为对象的过程称为对象的反序列化。

什么时候需要序列化与反序列化?

  当我们只在本地 JVM 里运行下 Java 实例,这个时候是不需要什么序列化和反序列化的,但当我们需要将内存中的对象持久化到磁盘,数据库中时, 当我们需要与浏览器进行交互时,当我们需要实现 RPC 时, 这个时候就需要序列化和反序列化了。
  对于与浏览器的交互,采用json格式,json格式本身就是将一个对象转换为字符串,而字符串同样是实现了序列化的。
  对于将数据持久化到数据库,我们同样是将属性保存到数据库,而不是将对象保存到数据库。


为什么要实现 Serializable 接口?

  在 Java 中实现了 Serializable 接口后, JVM 会在底层帮我们实现序列化和反序列化。


为什么还要指定serialVersionUID的值?

  如果不显示指定serialVersionUID,JVM在序列化时会根据属性自动生成一个serialVersionUID,然后与属性一起序列化,再进行持久化或网络传输。
  在反序列化时,JVM会再根据属性自动生成一个新版 serialVersionUID,然后将这个新版serialVersionUID与序列化时生成的旧版serialVersionUID进行比较,如果相同则反序列化成功,否则报错。
  如果显示指定了serialVersionUID,JVM在序列化和反序列化时仍然都会生成一个serialVersionUID,但值为我们显示指定的值,这样在反序列化时新旧版本的 serialVersionUID 就一致了。
  默认的serialVersionUID,是根据类的属性生成的,如果类的属性发生变化,serialVersionUID的值对应会发生变化,这时候去反序列化原有的对象就会失败。而显式指定之后则解决了这个问题。


序列化的其他特性

  被transient关键字修饰的属性不会被序列化,static属性也不会被序列化。

static 属性为什么不会被序列化?

  因为序列化是针对对象而言的,而static属性优先于对象存在,随着类的加载而加载,所以不会被序列化。
  其实serialVersionUID属性并没有被序列化,JVM在序列化对象时会自动生成一个serialVersionUID,然后将我们显示指定的serialVersionUID属性值赋给自动生成的serialVersionUID。