java-序列化

什么是序列化

Java序列化是指把Java对象转换为字节序列的过程

Java反序列化是指把字节序列恢复为Java对象的过程

为什么需要使用序列化和反序列化

不同进程/程序间进行远程通信时,会相互发送各种类型的数据,包括文本、图片、音频、视频等,而这些数据都会以二进制序列的形式在网络上传送。

当两个Java进程进行通信时,对于进程间的对象传送需要使用Java序列化与反序列化了。发送方需要把这个Java对象转换为字节序列,接收方则需要将字节序列中恢复成Java对象。

序列化有哪些好处

①实现了对象数据的持久化,通过序列化可以把数据永久地保存到硬盘上(例如:存储在文件里)。

②利用序列化实现远程通信,即:能够在网络上传输对象。

Serializable 和 Parcelable 的区别

Serializable

Serializable接口没有方法和属性,只是一个识别类可被序列化的标志。

Serializable是通过I/O读写存储在磁盘上的,通过反射解析出对象描述、属性描述,通过HandleTable缓存解析信息,之后解析成二进制,存储、传输。

Parcel

Parcel翻译过来是打包的意思,其实就是包装了我们需要传输的数据,然后在Binder中跨进程传输,将序列化之后的数据写入到一个共享内存中,其他进程通过Parcel可以从这块共享内存中读出字节流,并反序列化成对象。

它的各种writeXXX方法,在native层都是会调用Parcel.cpp的write方法。

总结:

①内存的读写速度通常大于I/O读写,所以在 Android 中传递数据优先选择 Parcelable。

②Serializable使用反射,序列化和反序列化过程需要大量 I/O 操作;

Parcelable 自己实现封送和解封(marshalled & unmarshalled),不需要用反射,数据存放在 Native内存中,效率要快很多。

什么是serialVersionUID

序列化是将对象的状态信息转换为可存储或传输的形式的过程。Java对象是保存在JVM的堆内存中的,也就是说,如果JVM堆不存在了,那么对象也就跟着消失了。

而序列化提供了一种方案,可以让你在即使JVM停机的情况下也能把对象保存下来。就像我们平时用的U盘一样。把Java对象序列化成可存储或传输的形式(例如:二进制流),比如保存文件。这样,当再次需要这个对象的时候,从文件中读取出二进制流,再从二进制流中反序列化出对象。

虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的点是两个类的序列化ID是否一致,这个所谓的序列化ID,就是我们在代码中定义的serialVersionUID。

为什么还要显示指定serialVersionUID的值

①如果没有指定serialVersionUID, JVM在序列化时会根据属性自动生成一个serialVersionUID,然后与属性一起序列化,再进行持久化或网络传输。

在反序列化时,JVM会再根据属性自动生成一个新版serialVersionUID,然后将这个新版serialVersionUID与序列化时生成的旧版serialVersionUID进行比较,如果相同则反序列化成功,否则报错。

②如果有指定了serialVersionUID,JVM在序列化和反序列化时仍然都会生成一个serialVersionUID,但值为我们显示指定的值,这样在反序列化时新旧版本的serialVersionUID就一致了。

在实际开发中,没有显示指定serialVersionUID的情况会导致什么问题?

如果我们的类写完后不再修改,那不会有问题,但这在实际开发中是不可能的,我们的类会不断迭代,一旦类被修改了,那旧对象反序列化就会报错。

所以在实际开发中,我们都会显示指定一个serialVersionUID,值是多少无所谓,只要不变就行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值