Java序列化

什么是Java序列化留搔?

持久化內(nèi)存中的對象到硬件設(shè)備贴浙,會把其狀態(tài)保存為一組字節(jié)砂吞,在未來,再將這些字節(jié)組裝成對象崎溃,這就是序列化和反序列化蜻直。
必須注意地是,對象序列化保存的是對象的"狀態(tài)"袁串,即它的成員變量概而。由此可知,對象序列化不會關(guān)注類中的靜態(tài)變量以及被transient關(guān)鍵字修飾的成員變量般婆。

Java序列化的應(yīng)用場景

  • 把對象持久化到存儲設(shè)備上
  • 對象通過網(wǎng)絡(luò)傳輸給其它客戶端

基本知識點

Serializable概述

  • 對于任何需要被序列化的對象,都必須要實現(xiàn)接口Serializable,它只是一個標識接口朵逝,本身沒有任何成員蔚袍,只是用來標識說明當前的實現(xiàn)類的對象可以被序列化.
  • 如果父類實現(xiàn)序列化,子類自動實現(xiàn)序列化配名,不需要顯式實現(xiàn)Serializable接口啤咽。

transient關(guān)鍵字

如果某實例變量不能或不應(yīng)該被序列化,就把它標記為transient的變量渠脉,這樣序列化程序就會把它跳過宇整。
transient的引用變量會以null返回,基本數(shù)據(jù)類型會以相應(yīng)的默認值返回芋膘。
(例如:引用類型沒有實現(xiàn)Serializable鳞青,或者動態(tài)數(shù)據(jù)只可以在執(zhí)行時求出而不能或不必存儲)

serialVersionUID

作用:
用來輔助序列化和反序列化過程的,原則上序列化后的數(shù)據(jù)中的serialVersionUID只有和當前類的serialVersionUID相同才能夠正常地被反序列化为朋。

工作機制:
序列化的時候系統(tǒng)會把當前類的serialVersionUID寫入序列化的文件中臂拓,當反序列化的時候系統(tǒng)會去檢測文件中的serialVersionUID,看它是否和當前類的serialVersionUID一致习寸,如果一致就說明序列化的類的版本和當前類的版本是相同的胶惰,這個時候可以成功反序列化;否則就說明當前類和序列化的類相比發(fā)生了某些變換霞溪,比如成員變量的數(shù)量孵滞,類型可能發(fā)生了改變中捆,這個時候無法正常反序列化的。并會產(chǎn)生以下異常:

java.io.InvalidClassException: 實體類(pojo); local class incompatible: stream classdesc serialVersionUID = 812952289507407815, local class serialVersionUID = -7688346538714640295 

兩種指定serialVersionUID的方式:

  • 手動指定serialVersionUID的值坊饶,比如100L
  • 通過IDE根據(jù)當前類的結(jié)構(gòu)自動去生成它的hash值泄伪。

指定與不指定serialVersionUID有什么不同的結(jié)果?

  • 如果不手動指定serialVersionUID的值幼东,反序列化時當前類有所改變臂容,比如增加或者刪除了某些成員變量,那么系統(tǒng)就會重新計算當前類的hash值并把它賦值給serialVersionUID根蟹,這個時候當前類的serialVersionUID就和序列化的數(shù)據(jù)中的serialVersionUID不一致脓杉,于是反序列化失敗,程序就會拋出java.io.InvalidClassException简逮。
  • 如果手動指定了它以后球散,就可以在很大的程度上避免反序列化過程的失敗。比如當版本升級后散庶,我們可能刪除了某個成員變量也可能增加了一些新的成員變量蕉堰,這個時候我們的反序列化過程仍然能成功,程序仍然能夠最大限度地恢復(fù)數(shù)據(jù)悲龟,相反屋讶,如果不指定serialVersionUID的話,程序則會crash须教。
  • 如果類結(jié)構(gòu)發(fā)生了非常規(guī)性改變皿渗,比如修改了類名,修改了成員變量的類型轻腺,這個時候盡管serialVersionUID驗證通過乐疆,但是反序列化過程還是會失敗,因為類的結(jié)構(gòu)有了毀滅性的改變贬养,根本無法從老版本的數(shù)據(jù)中還原出一個新的類結(jié)構(gòu)的對象挤土。

簡單實例

        File file = new File("box.out");

        FileOutputStream fileOutputStream = new FileOutputStream(file);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        objectOutputStream.writeObject(new Box(100, 100));
        objectOutputStream.close();

        FileInputStream fileInputStream = new FileInputStream(file);
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        Box o = (Box) objectInputStream.readObject();
        objectInputStream.close();
        System.out.println(o);

注意事項

  • 如果有不能被序列化的對象,執(zhí)行期間就會拋出NotSerializableException異常;
  • 序列化時误算,只對對象的狀態(tài)進行保存仰美,而不管對象的方法
  • 靜態(tài)變量和transient修飾的變量不會被序列化
  • 如果子類實現(xiàn)Serializable接口而父類未實現(xiàn)時,父類不會被序列化儿礼,但此時父類必須有個無參構(gòu)造方法筒占,否則會拋InvalidClassException異常。因為反序列化時會恢復(fù)原有子對象的狀態(tài)蜘犁,而父類的成員變量也是原有子對象的一部分翰苫。由于父類沒有實現(xiàn)序列化接口,即使沒有顯示調(diào)用,也會默認執(zhí)行父類的無參構(gòu)造函數(shù)使變量初始化奏窑。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末导披,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子埃唯,更是在濱河造成了極大的恐慌撩匕,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墨叛,死亡現(xiàn)場離奇詭異止毕,居然都是意外死亡,警方通過查閱死者的電腦和手機漠趁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進店門扁凛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人闯传,你說我怎么就攤上這事谨朝。” “怎么了甥绿?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵字币,是天一觀的道長。 經(jīng)常有香客問我共缕,道長洗出,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任图谷,我火速辦了婚禮翩活,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜓萄。我一直安慰自己隅茎,他們只是感情好澄峰,可當我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布嫉沽。 她就那樣靜靜地躺著,像睡著了一般俏竞。 火紅的嫁衣襯著肌膚如雪绸硕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天魂毁,我揣著相機與錄音玻佩,去河邊找鬼。 笑死席楚,一個胖子當著我的面吹牛咬崔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼垮斯,長吁一口氣:“原來是場噩夢啊……” “哼郎仆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兜蠕,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤扰肌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后熊杨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體曙旭,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年晶府,在試婚紗的時候發(fā)現(xiàn)自己被綠了桂躏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡郊霎,死狀恐怖沼头,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情书劝,我是刑警寧澤进倍,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站购对,受9級特大地震影響猾昆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骡苞,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一垂蜗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧解幽,春花似錦贴见、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至霜定,卻和暖如春档悠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背望浩。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工辖所, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人磨德。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓缘回,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子酥宴,可洞房花燭夜當晚...
    茶點故事閱讀 45,926評論 2 361

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

  • JAVA序列化機制的深入研究 對象序列化的最主要的用處就是在傳遞,和保存對象(object)的時候,保證對象的完整...
    時待吾閱讀 10,878評論 0 24
  • 如果你只知道實現(xiàn) Serializable 接口的對象揩环,可以序列化為本地文件。那你最好再閱讀該篇文章幅虑,文章對序列化...
    jiangmo閱讀 481評論 0 2
  • 什么是序列化 所謂的序列化丰滑,即把java對象以二進制形式保存到內(nèi)存、文件或者進行網(wǎng)絡(luò)傳輸倒庵。從二進制的形式恢復(fù)成為j...
    德彪閱讀 659評論 0 0
  • 聲明:原創(chuàng)文章褒墨,轉(zhuǎn)載請注明出處。http://www.reibang.com/u/e02df63eaa87 1擎宝、序...
    唐影若凡閱讀 399評論 0 0
  • 序列化是什么 信息的傳遞郁妈、交換支撐整個互聯(lián)網(wǎng)產(chǎn)業(yè),那么信息的交流的過程中遵循著什么樣的標準绍申。常見的網(wǎng)絡(luò)傳輸協(xié)議有 ...
    非典型程序員閱讀 2,295評論 0 5