亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java中對象序列化與反序列化詳解

2019-11-26 15:00:04
字體:
來源:轉載
供稿:網友

本文實例講述了Java中對象序列化與反序列化。分享給大家供大家參考。具體如下:

一、簡介

對象序列化(Serializable)是指將對象轉換為字節序列的過程,而反序列化則是根據字節序列恢復對象的過程。

序列化一般用于以下場景:

1.永久性保存對象,保存對象的字節序列到本地文件中;
2.通過序列化對象在網絡中傳遞對象;
3.通過序列化在進程間傳遞對象。

對象所屬的類必須實現Serializable或是Externalizable接口才能被序列化。對實現了Serializable接口的類,其序列化與反序列化采用默認的序列化方式,Externalizable接口是繼承了Serializable接口的接口,是對Serializable的擴展,實現了Externalizable接口的類完全自己控制序列化與反序列化行為。

Java.io.ObjectOutputStream代表對象輸出流,其方法writeObject(Object obj)可以實現對象的序列化,將得到的字節序列寫到目標輸出流中。

Java.io.ObjectInputStream代表對象輸入流,其readObject()方法能從源輸入流中讀取字節序列,將其反序列化為對象,并將其返回。

二、序列化的幾種方式

假設定義了一個Customer類,根據Customer實現序列化方式的不同,可能有以下幾種序列化方式:

1.實現Serializable,未定義readObject和writeObject方法

ObjectOutputStream使用JDK默認方式對Customer對象的非transient的實例變量進行序列化;
ObjectInputStream使用JDK默認方式對Customer對象的非transient的實例變量進行反序列化。

2.實現Serializable,并定義了readObject和writeObject方法

ObjectOutputStream調用Customer類的writeObject(ObjectOutputStream out)方法對Customer對象的非transient的實例變量進行序列化;
ObjectInputStream調用Customer類的readObject(ObjectInputStream in)方法對Customer對象的非transient的實例變量進行反序列化。

3.實現Externalizable,定義readExternal和writeExternal方法

ObjectOutputStream調用Customer類的writeExternal方法對Customer對象的非transient實例變量進行序列化;
ObjectInputStream首先通過Customer類的無參數構造函數實例化一個對象,再用readExternal方法對Customer對象的非transient實例變量進行反序列化。

三、Serializable接口

類通過實現 java.io.Serializable 接口以啟用其序列化功能。未實現此接口的類將無法使其任何狀態序列化或反序列化。可序列化類的所有子類型本身都是可序列化的。序列化接口沒有方法或字段,僅用于標識可序列化的語義。

在反序列化過程中,將使用該類的公用或受保護的無參數構造方法初始化不可序列化類的字段??尚蛄谢淖宇惐仨毮軌蛟L問無參數構造方法??尚蛄谢宇惖淖侄螌脑摿髦谢謴汀?/p>

當遍歷一個類視圖時,可能會遇到不支持 Serializable 接口的對象。在此情況下,將拋出 NotSerializableException,并將標識不可序列化對象的類。

1.準確簽名

在序列化和反序列化過程中需要特殊處理的類必須使用下列準確簽名來實現特殊方法:

private void writeObject(java.io.ObjectOutputStream out) throws IOException
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
private void readObjectNoData() throws ObjectStreamException;

writeObject 方法負責寫入特定類的對象的狀態,以便相應的 readObject 方法可以恢復它。通過調用 out.defaultWriteObject 可以調用保存 Object 的字段的默認機制。該方法本身不需要涉及屬于其超類或子類的狀態。通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數據類型的方法將各個字段寫入 ObjectOutputStream,狀態可以被保存。

readObject 方法負責從流中讀取并恢復類字段。它可以調用 in.defaultReadObject 來調用默認機制,以恢復對象的非靜態和非瞬態字段。defaultReadObject 方法使用流中的信息來分配流中通過當前對象中相應指定字段保存的對象的字段。這用于處理類演化后需要添加新字段的情形。該方法本身不需要涉及屬于其超類或子類的狀態。通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數據類型的方法將各個字段寫入 ObjectOutputStream,狀態可以被保存。

在序列化流不列出給定類作為將被反序列化對象的超類的情況下,readObjectNoData 方法負責初始化特定類的對象狀態。這在接收方使用的反序列化實例類的版本不同于發送方,并且接收者版本擴展的類不是發送者版本擴展的類時發生。在序列化流已經被篡改時也將發生;因此,不管源流是“敵意的”還是不完整的,readObjectNoData 方法都可以用來正確地初始化反序列化的對象。

將對象寫入流時需要指定要使用的替代對象的可序列化類,應使用準確的簽名來實現此特殊方法:

ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
此writeReplace方法將由序列化調用,前提是如果此方法存在,而且它可以通過被序列化對象的類中定義的一個方法訪問。因此,該方法可以擁有私有 (private)、受保護的(protected) 和包私有 (package-private) 訪問。子類對此方法的訪問遵循 java 訪問規則。

在從流中讀取類的一個實例時需要指定替代的類應使用的準確簽名來實現此特殊方法。

ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
此readResolve方法遵循與writeReplace相同的調用規則和訪問規則。
如果一個類定義了readResolve方法,那么在反序列化的最后將調用readResolve方法,該方法返回的對象為反序列化的最終結果。

2.serialVersionUID

序列化運行時使用一個稱為 serialVersionUID 的版本號與每個可序列化類相關聯,該序列號在反序列化過程中用于驗證序列化對象的發送者和接收者是否為該對象加載了與序列化兼容的類。如果接收者加載的該對象的類的 serialVersionUID 與對應的發送者的類的版本號不同,則反序列化將會導致 InvalidClassException。可序列化類可以通過聲明名為 "serialVersionUID" 的字段(該字段必須是靜態 (static)、最終 (final) 的 long 型字段)顯式聲明其自己的 serialVersionUID:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
如果可序列化類未顯式聲明 serialVersionUID,則序列化運行時將基于該類的各個方面計算該類的默認 serialVersionUID 值,如“Java(TM) 對象序列化規范”中所述。不過,強烈建議 所有可序列化類都顯式聲明 serialVersionUID 值,原因是計算默認的 serialVersionUID 對類的詳細信息具有較高的敏感性,根據編譯器實現的不同可能千差萬別,這樣在反序列化過程中可能會導致意外的 InvalidClassException。因此,為保證 serialVersionUID 值跨不同 java 編譯器實現的一致性,序列化類必須聲明一個明確的 serialVersionUID 值。還強烈建議使用 private 修飾符顯示聲明 serialVersionUID(如果可能),原因是這種聲明僅應用于直接聲明類 -- serialVersionUID 字段作為繼承成員沒有用處。數組類不能聲明一個明確的 serialVersionUID,因此它們總是具有默認的計算值,但是數組類沒有匹配 serialVersionUID 值的要求。

3.Externalizable接口

Externalizable是Serailizable的擴展,實現Externalizable接口的類其序列化有以下特點:
序列化時調用類的方法writeExternal,反序列化調用readExternal方法;
在執行反序列化時先調用類的無參數構造函數,這一點與默認的反序列化是不同的,因此對實現Externalizable接口來實現序列化的類而言,必須提供一個public的無參數構造函數,否則在反序列化時將出現異常。

四、總結

如果采用默認的序列化方式,只要讓一個類實現Serializable接口,其實例就可以被序列化。通常,專門為繼承而設計的類應該盡量不要實現Serializable接口,因為一旦父類實現了Serializable接口,其所有子類也都是可序列化的了。

默認的序列化方式的不足之處:

1.直接對對象的不宜對外公開的敏感數據進行序列化,這是不安全的;
2.不會檢查對象的成員變量是否符合正確的約束條件,有可能被篡改數據而導致運行異常;
3.需要對對象圖做遞歸遍歷,如果對象圖很復雜,會消耗很多資源,設置引起Java虛擬機的堆棧溢出;
4.使類的接口被類的內部實現約束,制約類的升級與維護。

通過實現Serializable接口的private類型的writeObject()和readObject(),或是實現Externalizable接口,并實現writeExternal()與readExternal()方法,并提供public類型的無參數構造函數兩種方式來控制序列化過程可以有效規避默認序列化方式的不足之處。

希望本文所述對大家的java程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美怡红院视频一区二区三区| 日本高清视频精品| 国产97在线观看| 国内精品久久久久久久久| 在线视频日韩精品| 538国产精品一区二区免费视频| 2021国产精品视频| 久久精品电影网| 亚洲国产精品成人精品| 91深夜福利视频| 久久99久国产精品黄毛片入口| 黄色成人在线免费| 亚洲国产精品久久久久秋霞不卡| 热re91久久精品国99热蜜臀| 亚洲黄一区二区| 九九视频这里只有精品| 成人免费午夜电影| 91爱视频在线| 亚洲第一中文字幕在线观看| 日韩国产在线播放| 国产精品99久久久久久www| 亚洲欧洲偷拍精品| 国产精品美女久久久免费| 亚洲国产毛片完整版| 久久久久久亚洲精品中文字幕| 欧美视频国产精品| 欧美高清视频在线播放| 国产美女精品免费电影| 91精品视频免费看| 精品中文字幕在线观看| www.精品av.com| 欧美激情日韩图片| 韩国视频理论视频久久| 日韩成人性视频| 国产精品美女久久久久av超清| 欧美裸体xxxx极品少妇软件| 亚洲高清一区二| 一区二区三区回区在观看免费视频| 欧美最猛性xxxxx(亚洲精品)| 色中色综合影院手机版在线观看| 国产精品观看在线亚洲人成网| 在线成人激情视频| 欧美猛交ⅹxxx乱大交视频| 久久久成人av| 日韩成人xxxx| 日韩电影免费在线观看中文字幕| 91国产美女视频| 亚洲91av视频| 国产精品极品尤物在线观看| 国产福利精品在线| 久久香蕉频线观| 日韩国产欧美精品在线| 亚洲精品国产精品乱码不99按摩| 韩国三级电影久久久久久| xvideos成人免费中文版| 成人在线一区二区| 精品视频在线导航| 亚洲国产精品字幕| 亚洲一区二区中文| 日本精品久久久| 国模精品视频一区二区三区| 日韩欧美aⅴ综合网站发布| 欧美性xxxx在线播放| 91精品国产91久久久久久不卡| 欧美大肥婆大肥bbbbb| 亚洲国产精品va| 精品福利在线看| 久久久999精品免费| 国产欧美日韩综合精品| 欧美孕妇与黑人孕交| 亚洲字幕在线观看| 性欧美长视频免费观看不卡| 日韩精品在线免费| 亚洲精品国产欧美| 精品人伦一区二区三区蜜桃网站| 久久全球大尺度高清视频| 亚洲欧洲偷拍精品| 日韩精品有码在线观看| 91精品免费看| 色偷偷偷亚洲综合网另类| 亚洲激情在线观看| 精品久久久久久中文字幕| 2019亚洲男人天堂| 国产一区二区三区在线| 国产免费一区二区三区在线观看| 精品中文字幕久久久久久| 国产精品视频网址| 欧美大片在线免费观看| 亚洲欧美中文字幕在线一区| 伦理中文字幕亚洲| 国产一区二区三区在线免费观看| 欧美专区第一页| 成人福利网站在线观看| 国产热re99久久6国产精品| 疯狂蹂躏欧美一区二区精品| 日韩电影免费在线观看| 91在线免费视频| 91理论片午午论夜理片久久| 91探花福利精品国产自产在线| 成人疯狂猛交xxx| 国产精品一二三在线| 亚洲第一福利网站| 亚洲高清免费观看高清完整版| 国产精品va在线播放我和闺蜜| 午夜精品久久久久久久久久久久| 日韩av在线免费播放| wwwwwwww亚洲| 高清在线视频日韩欧美| 日韩视频欧美视频| 久久久中精品2020中文| 日本精品一区二区三区在线播放视频| 亚洲最大中文字幕| 国产成人啪精品视频免费网| 中文在线资源观看视频网站免费不卡| 亚洲国产日韩精品在线| 国产精品欧美日韩一区二区| 97视频在线看| 国产亚洲精品成人av久久ww| 亚洲黄一区二区| 91超碰中文字幕久久精品| 欧美专区中文字幕| 韩国19禁主播vip福利视频| 中文字幕一精品亚洲无线一区| 精品欧美国产一区二区三区| 日韩在线激情视频| 中文字幕欧美在线| 久久青草精品视频免费观看| 欧美性xxxxx| 国产69精品久久久久9999| 成人黄色生活片| 成人妇女淫片aaaa视频| 欧美性受xxxx黑人猛交| 国产视频综合在线| 亚洲天堂一区二区三区| 最新国产成人av网站网址麻豆| 久久手机免费视频| 日韩视频免费看| 国产日韩欧美视频在线| 日韩欧美有码在线| 国产精品热视频| 久久综合88中文色鬼| 久久亚洲精品一区二区| 国内揄拍国内精品| 亚洲欧美综合区自拍另类| 国产精品视频精品视频| 亚洲精品久久7777777| 成人黄色av免费在线观看| 全色精品综合影院| 中文字幕亚洲无线码a| 不卡av电影在线观看| 中文字幕国产日韩| 日韩美女视频免费在线观看| 国产精品www| 日韩欧美成人精品| 久久国产精品99国产精| 久久久国产一区| 欧美精品国产精品日韩精品| 久久噜噜噜精品国产亚洲综合| 亚洲人成电影网站色…| 91av免费观看91av精品在线| 日韩中文字幕网| 欧美野外wwwxxx| 久久成人人人人精品欧| 日韩在线播放视频|