序列化与反序列化
序列化与反序列化
- 序列化:把对象转换为字节数组的过程称为对象的序列化。
- 反序列化:把字节序列转换为对象的过程称为对象的反序列化。
什么时候需要序列化与反序列化?
当我们只在本地 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。