Serializable 和Parcelable 的区别(Android每日面试题)
前言
看见即降服,这句话说的是一件事物,只要你看得到,你就能得到。
对我来说记录就是看见。
面试题不只是为了面试,更是为了帮助我们更深入地理解我们已知的知识。
自我检讨
本篇文章中的引用稍微多了一下(额,好吧,好像我每篇文章都有好多引用),请大家谅解,不过引用的文章确实是我想要的内容,讲得也挺好的,希望大家可以去阅读一下,帮助自己理解。
序列化
对于本文的这个问题,我觉得我们得先了解序列化这个概念,什么是序列化(反序列化)?序列化有什么作用?怎么实现序列化?Ok,灵魂三连问!
什么是序列化(反序列化)
具体学术级别的概念可以阅读文末参考。我在这里用我的理解来简单描述下:
- 序列化:当我们需要把程序内存中堆上
new Person(18,"小明")
这个对象存储下来(如放到磁盘的文件)或者用于网络传输时,我们必须将这个对象流化(也就是将对象变为有序的字节流),这个过程就是序列化。那么问题来了,为什么要流化呢?因为只有流化的对象,才能被传输,被存储。咦?我这个解释怎么怪怪的?好吧,流化以后的对象的真容大家可以看一下文末参考文章的最后,它是一串字节流,所以就可以被网络传输,被存储啦。不晓得有没有讲清楚?(大家可以读一下这篇文章的What部分). - 反序列化:反序列化就是序列化的反操作,就是把序列化生成的字节流转为我们内存的对象。
序列化有什么作用
这个作用以及在上面提到过了,用于网络传输和存储。
怎么实现序列化
两种方式:
1.实现Serializable接口
2.实现Parcelable接口
Serializable
首先这个接口是Java自带哦。
怎么使用呢?很简单,大家也都知道的,只需要给我们需要序列化的类实现这个接口就行了(实现这个接口就代表我们的类可以被序列化/反序列化),然后就可以使用ObjectOutputStream
序列化和ObjectInputStream
反序列化了。(具体的可以参考这篇文章)
Serializable
的底层原理,也就是ObjectOutputStream
和ObjectInputStream
到底做了什么,大家可以阅读这篇文章的Why部分。
Parcelable
这个接口是Android专有的。这里额外多说一句,当我们需要将我们的对象进行网络传输或存储到文件中时,使用Serializable
;当我们需要将我们的对象在进程间传递通信时,使用Parcelable
(文末有解释)。
使用方式:实现Parcelable
接口,重写describeContents()
,writeToParcel(Parcel dest, @WriteFlags int flags)
,并添加一个静态成员变量CREATOR
,这个变量还需要实现Parcelable.Creator
接口。
在说Parcelable
的底层原理之前,我们需要了解一下Parcel
这个类,知道了它就知道Parcelable
的底层原理。这里是Parcel
的使用和实现,大家看完应该就能清楚Parcelable
底层是如何序列化/反序列化的。
区别
在我们谈论区别之前我们先看下这个SO的帖子,看下老外的解释。
好了,最后解释一下,为什么IPC的时候用Parcelable
,网络传输和保存至磁盘的时候用Serializable
。还是先来一个文章引用,然后我自己再解释一下。
- IPC的时候用
Parcelable
,是因为它效率高,虽然我们在使用Intent
传递的时候也可以使用Serializable
的对象。 - 网络传输和保存至磁盘的时候用
Serializable
,是因为Parcelable
不能保证,当外部条件发生变化时数据的连续性。也可以看官网对Parcel
的解释:
As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.
参考
转载自:https://juejin.cn/post/6883309627933458445