Android Serializable與Parcelable 分析對比整理

1.Serializable接口

序列化與反序列化就是JAVA對象與一串字節(jié)流之間的相互轉(zhuǎn)換, 我們在程序中創(chuàng)建的JAVA對象只存在于JVM中, 當(dāng)程序退出時, 這些對象也就消失了, 而序列化正是為了將這些對象保存起來以僅將來使用,也可以將已經(jīng)序列化的對象傳送給其他JVM來使用,這些序列化的字節(jié)流是于JVM無關(guān)的, 也就是說一個JVM序列化的對象可以在另一個JVM中反序列化.
序列化分為兩大部分:序列化和反序列化。 序列化是這個過程的第一部分酝掩,將數(shù)據(jù)分解成字節(jié)流鳞芙,以便存儲在文件中或在網(wǎng)絡(luò)上傳輸。 反序列化就是打開字節(jié)流并重構(gòu)對象。 對象序列化不僅要將基本數(shù)據(jù)類型轉(zhuǎn)換成字節(jié)表示原朝,有時還要恢復(fù)數(shù)據(jù)驯嘱。 恢復(fù)數(shù)據(jù)要求有恢復(fù)數(shù)據(jù)的對象實(shí)例。 ObjectOutputStream中的序列化過程與字節(jié)流連接喳坠,包括對象類型和版本信息鞠评。 反序列化時,JVM用頭信息生成對象實(shí)例丙笋,然后將對象字節(jié)流中的數(shù)據(jù)復(fù)制到對象數(shù)據(jù)成員中谢澈。
Java的對象序列化只要對象實(shí)現(xiàn)了Serializable接口
這個接口只是一個標(biāo)記接口煌贴,不包含任何的方法御板,

使用JAVA提供的序列化機(jī)制有以下兩條需要遵守的條件:

1.該類必須直接實(shí)現(xiàn)java.io.Serializable接口或者間接從其繼承樹中實(shí)現(xiàn)該接口(也就是他的某個父類實(shí)現(xiàn)了這個接口);
2.對于該類的所有無法序列化的屬性(本文指字段field, 而不是嚴(yán)格意義上的屬性property, 下同)必須使用transient修飾.
補(bǔ)充說明:
從其繼承樹中實(shí)現(xiàn)Serializable接口指的是該類的某個父類實(shí)現(xiàn)了這個接口, 要注意的是Object類并沒有實(shí)現(xiàn)該接口, 也就是說默認(rèn)的情況下我們定義的類是不支持序列化的, 而JDK提供的某些類如String, 數(shù)組等實(shí)現(xiàn)了該接口;
無法序列化的屬性包括兩種:一種是主觀上不想保存的屬性, 如動態(tài)生成的屬性或者考慮到性能上的要求不準(zhǔn)備保存的屬性; 另一種是由于該屬性的類型沒有實(shí)現(xiàn)序列化而無法保存的屬性, 如Thread類型的屬性;
安全方面的原因,比如一個對象擁有private牛郑,public等field怠肋,對于一個要傳輸?shù)膶ο螅热鐚懙轿募团螅蛘哌M(jìn)行rmi傳輸?shù)鹊润细鳎谛蛄谢M(jìn)行傳輸?shù)倪^程中,這個對象的private等域是不受保護(hù)的础芍。

transient

變量修飾符杈抢,如果用transient聲明一個實(shí)例變量,當(dāng)對象存儲時仑性,它的值不需要維持惶楼。
換句話來說就是,用transient關(guān)鍵字標(biāo)記的成員變量不參與序列化過程诊杆。Serializable序列化不保存靜態(tài)變量歼捐,可以使用Transient關(guān)鍵字對部分字段不進(jìn)行序列化,也可以覆蓋writeObject晨汹、readObject方法以實(shí)現(xiàn)序列化過程自定義豹储。

場景:某個類的有些屬性需要序列化,而其他屬性不需要被序列化淘这,打個比方剥扣,如果一個用戶有一些敏感信息(如密碼,銀行卡號等)铝穷,為了安全起見钠怯,不希望在網(wǎng)絡(luò)操作(主要涉及到序列化操作,本地序列化緩存也適用)中被傳輸氧骤,這些信息對應(yīng)的變量就可以加上transient關(guān)鍵字呻疹。換句話說,這個字段的生命周期僅存于調(diào)用者的內(nèi)存中而不會寫到磁盤里持久化。

序列化過程

如果我們想要序列化一個對象刽锤,首先要創(chuàng)建某些OutputStream(如FileOutputStream镊尺、ByteArrayOutputStream等),然后將這些OutputStream封裝在一個ObjectOutputStream中并思。這時候庐氮,只需要調(diào)用writeObject()方法就可以將對象序列化,并將其發(fā)送給OutputStream(記姿伪恕:對象的序列化是基于字節(jié)的弄砍,不能使用Reader和Writer等基于字符的層次結(jié)構(gòu))。而飯序列的過程(即將一個序列還原成為一個對象)输涕,需要將一個InputStream(如FileInputstream音婶、ByteArrayInputStream等)封裝在ObjectInputStream內(nèi),然后調(diào)用readObject()即可莱坎。
序列化算法一般會按步驟做如下事情:

◆將對象實(shí)例相關(guān)的類元數(shù)據(jù)輸出衣式。
◆遞歸地輸出類的超類描述直到不再有超類。
◆類元數(shù)據(jù)完了以后檐什,開始從最頂層的超類開始輸出對象實(shí)例的實(shí)際數(shù)據(jù)值碴卧。
◆從上至下遞歸輸出實(shí)例的數(shù)據(jù)

對象序列化過程不僅僅保存單個對象,還能追蹤對象內(nèi)所包含的所有引用乃正,并保存那些對象(這些對象也需實(shí)現(xiàn)了Serializable接口)
任何類型只要實(shí)現(xiàn)了Serializable接口住册,就可以被保存到文件中,或者作為數(shù)據(jù)流通過網(wǎng)絡(luò)發(fā)送到別的地方瓮具。

反序列化

序列化機(jī)制并不要求該類具有一個無參的構(gòu)造方法, 因?yàn)樵诜葱蛄谢倪^程中實(shí)際上是去其繼承樹上找到一個沒有實(shí)現(xiàn)Serializable接口的父類(最終會找到Object), 然后構(gòu)造該類的對象, 再逐層往下的去設(shè)置各個可以反序列化的屬性(也就是沒有被transient修飾的非靜態(tài)屬性).

在反序列的JVM上必須能夠找到該類(有可能序列化和反序列化并不是在同一個JVM上進(jìn)行的), 否則就會拋出ClassNotFoundException;
由于ObjectInputStream.readObject()方法可以反序列化任何類的對象, 所以其返回類型為Object, 我們需要將其強(qiáng)轉(zhuǎn)成具體的類;
如何對不滿足序列化機(jī)制的兩個要求的類進(jìn)行序列化, 則會拋出NotSerializableException;
如果JVM發(fā)現(xiàn)序列化與反序列化的類文件"不相同", 則會拋出InvalidClassException.

Parcelable 實(shí)現(xiàn)過程

1.實(shí)現(xiàn)Parcelable接口

2.實(shí)現(xiàn)接口中的兩個方法

public int describeContents();
public void writeToParcel(Parcel dest, int flags);

第一個方法是內(nèi)容接口描述荧飞,默認(rèn)返回0就可以了
第二個方法是將我們的對象序列化一個Parcel對象,也就是將我們的對象存入Parcel中 .

3.實(shí)例化靜態(tài)內(nèi)部對象CREATOR實(shí)現(xiàn)接口Parcelable.Creator搭综,實(shí)例化CREATOR時要實(shí)現(xiàn)其中的兩個方法垢箕,其中createFromParcel的功能就是從Parcel中讀取我們的對象。

對比分析

Serializable是Java的實(shí)現(xiàn)方式,可能會頻繁的IO操作,所以消耗比較大,但是實(shí)現(xiàn)方式簡單 Parcelable是Android提供的方式,效率比較高,但是實(shí)現(xiàn)起來復(fù)雜一些Parcelable的性能比Serializable好兑巾,在內(nèi)存開銷方面較小条获,所以在內(nèi)存間數(shù)據(jù)傳輸時推薦使用Parcelable,如activity間傳輸數(shù)據(jù)蒋歌,而Serializable可將數(shù)據(jù)持久化方便保存帅掘,所以在需要保存或網(wǎng)絡(luò)傳輸數(shù)據(jù)時選擇Serializable.

在讀寫數(shù)據(jù)的時候,Parcelable是在內(nèi)存中直接進(jìn)行讀寫,而Serializable是通過使用IO流的形式將數(shù)據(jù)讀寫入在硬盤上.
Serializable在序列化操作的時候會產(chǎn)生大量的臨時變量,(原因是使用了反射機(jī)制)從而可能導(dǎo)致GC的頻繁調(diào)用。
Parcelable是以Ibinder作為信息載體的.在內(nèi)存上的開銷比較小,因此在內(nèi)存之間進(jìn)行數(shù)據(jù)傳遞的時候,使用Parcelable,

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末堂油,一起剝皮案震驚了整個濱河市修档,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌府框,老刑警劉巖吱窝,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡院峡,警方通過查閱死者的電腦和手機(jī)兴使,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來照激,“玉大人发魄,你說我怎么就攤上這事×├” “怎么了励幼?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長口柳。 經(jīng)常有香客問我苹粟,道長,這世上最難降的妖魔是什么啄清? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任六水,我火速辦了婚禮俺孙,結(jié)果婚禮上辣卒,老公的妹妹穿的比我還像新娘。我一直安慰自己睛榄,他們只是感情好荣茫,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著场靴,像睡著了一般啡莉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旨剥,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天咧欣,我揣著相機(jī)與錄音,去河邊找鬼轨帜。 笑死魄咕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蚌父。 我是一名探鬼主播哮兰,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼苟弛!你這毒婦竟也來了喝滞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤膏秫,失蹤者是張志新(化名)和其女友劉穎右遭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡窘哈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年言蛇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宵距。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡腊尚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出满哪,到底是詐尸還是另有隱情婿斥,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布哨鸭,位于F島的核電站民宿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏像鸡。R本人自食惡果不足惜活鹰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望只估。 院中可真熱鬧志群,春花似錦、人聲如沸蛔钙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吁脱。三九已至桑涎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兼贡,已是汗流浹背攻冷。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留遍希,地道東北人等曼。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像孵班,于是被迫代替她去往敵國和親涉兽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 第四次參加現(xiàn)金流游戲篙程,本次選擇的職業(yè)是護(hù)士枷畏,初始工資收入3100,支出1980虱饿,月現(xiàn)金流1120拥诡。最近幾天触趴,在家里...
    蚊子_302c閱讀 208評論 0 0
  • 大家應(yīng)該都知道Android建議不要用Java枚舉,它占用內(nèi)存很大圖片 那實(shí)際開發(fā)中肯定是要用Java枚舉的渴肉,那有...
    WilsonMing閱讀 1,412評論 0 5
  • 黃沾老先生冗懦,香港中文大學(xué)畢業(yè),做過中學(xué)老師仇祭、記者披蕉、主持人、廣告公司CEO乌奇,拍過電影没讲,寫過六十幾本書。曾捉刀《射雕》...
    Lynn青君閱讀 533評論 0 3
  • 安裝和配置控制節(jié)點(diǎn)(Controller node) 在配置Openstack網(wǎng)絡(luò)(項(xiàng)目代號為neutron)服務(wù)...
    煙熏的皮囊閱讀 1,255評論 0 51