對象序列化

一. Serializable接口

該方法使用簡單,只需要將類實現(xiàn)Serializable接口并聲明一個serialVersionUID即可(serialVersionUID非必須,但建議)。

原因:為了避免因為增刪一些成員變量,導(dǎo)致反序列化失敗,建議手動指定serialVersionUID的值;如果類結(jié)構(gòu)發(fā)生毀滅性改變,即便serialVersionUID驗證通過,也會反序列化失敗。

serialVersionUID的工作機(jī)制:序列化的時候系統(tǒng)會把當(dāng)前類的serialVersionUID寫入序列化的文件中(也可能是其他中介),當(dāng)反序列化的時候系統(tǒng)就會去檢測文件中的serialVersionUID,看它是否和當(dāng)前類的serialVersionUID一致,如果一致就說明序列化的類的版本和當(dāng)前類的版本是相同的,這個時候就可以成功反序列化;否則就說明當(dāng)前類和序列化的類相比發(fā)生了變化,比如成員變量的數(shù)量、類型發(fā)生了改變,這時是無法正常反序列化的,會有異常InvalidClassException。

注意:

  • 靜態(tài)成員變量屬于類不屬于對象,不會參與序列化過程;
  • 用transient關(guān)鍵字標(biāo)記的成員變量不參與序列化過程。

二. Parcelable接口

該方法使用起來麻煩一些,需要實現(xiàn)序列化、反序列化和內(nèi)容描述等功能。

方法 功能
createFromParcel(Parcel in) 從序列化后的對象中創(chuàng)建原始對象
new Array(int size) 創(chuàng)建指定長度的原始對象數(shù)組
User(Parcel in) 從序列化后的對象中創(chuàng)建原始對象
writeToParcel(Parcel dest, int flags) 將當(dāng)前對象寫入序列化結(jié)構(gòu)中,其中flag表示有兩種值:0或者1。為1時標(biāo)識當(dāng)前對象需要作為返回值返回,不能立即釋放資源,幾乎所有情況都為0
describeContents 返回當(dāng)前對象的內(nèi)容描述。如果含有文件掃描符,返回1,否則返回0。幾乎所有情況都為0

注意:
在以Parcel為參的構(gòu)造函數(shù)中,如果有一個變量是可序列化對象,那么它的反序列化過程需要傳遞當(dāng)前線程的上下文類加載器,否則會報無法找到類的錯誤。

book = in.readParcelable(Thread.currentThread().getContextClassLoader());

對比:
Serializable是Java中的序列化接口,使用簡單但開銷很大,序列化和反序列化過程都需要大量的I/O操作;Parcelable是Android中的序列化方式,更適用于Android平臺,效率很高,但使用起來稍微麻煩點。內(nèi)存序列化上,首選Parcelable;將對象序列化到存儲設(shè)備或通過網(wǎng)絡(luò)傳輸時,建議使用Serializable。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容