中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

Java序列化(Serializable)與反序列化
來源:易賢網 閱讀:1366 次 日期:2015-04-29 14:08:02
溫馨提示:易賢網小編為您整理了“Java序列化(Serializable)與反序列化”,方便廣大網友查閱!

序列化是干什么的

簡單說就是為了保存在內存中的各種對象的狀態(也就是實例變量,不是方法),并且可以把保存的對象狀態再讀出來。雖然你可以用你自己的各種各樣的方法來保 存object states,但是Java給你提供一種應該比你自己好的保存對象狀態的機制,那就是序列化。

什么情況下需要序列化

當你想把的內存中的對象狀態保存到一個文件中或者數據庫中時候;

當你想用套接字在網絡上傳送對象的時候;

當你想通過RMI傳輸對象的時候;

序列化的幾種方式

在Java中socket傳輸數據時,數據類型往往比較難選擇。可能要考慮帶寬、跨語言、版本的兼容等問題。比較常見的做法有兩種:一是把對象包裝成JSON字符串傳輸,二是采用java對象的序列化和反序列化。隨著Google工具protoBuf的開源,protobuf也是個不錯的選擇。對JSON,Object Serialize,ProtoBuf 做個對比。

Object Serialize

Java的序列化機制是通過在運行時判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體(類)的serialVersionUID進行比較,如果相同就認為是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常。

serialVersionUID 用來表明類的不同版本間的兼容性。有兩種生成方式:

一個是默認的1L,比如:private static final long serialVersionUID = 1L;

一個是根據類名、接口名、成員方法及屬性等來生成一個64位的哈希字段,比如: private static final long serialVersionUID = xxxxL;

下面來討論Java類中為什么需要重載 serialVersionUID 屬性?

當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。發送方需要把這個Java對象轉換為字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢復為Java對象。

把Java對象轉換為字節序列的過程稱為對象的序列化。

把字節序列恢復為Java對象的過程稱為對象的反序列化。

對象的序列化主要有兩種用途:(1)把對象的字節序列永久地保存到硬盤上,通常存放在一個文件中; (2)在網絡上傳送對象的字節序列;

java.io.ObjectOutputStream代表對象輸出流,它的writeObject(Object obj)方法可對參數指定的obj對象進行序列化,把得到的字節序列寫到一個目標輸出流中。

java.io.ObjectInputStream代表對象輸入流,它的readObject()方法從一個源輸入流中讀取字節序列,再把它們反序列化為一個對象,并將其返回。

只有實現了Serializable和Externalizable接口的類的對象才能被序列化。Externalizable接口繼承自Serializable接口,實現Externalizable接口的類完全由自身來控制序列化的行為,而僅實現Serializable接口的類可以采用默認的序列化方式 。

凡是實現Serializable接口的類都有一個表示序列化版本標識符的靜態變量:private static final long serialVersionUID;

類的serialVersionUID的默認值完全依賴于Java編譯器的實現,對于同一個類,用不同的Java編譯器編譯,有可能會導致不同的serialVersionUID,也有可能相同。為了提高serialVersionUID的獨立性和確定性,強烈建議在一個可序列化類中顯示的定義serialVersionUID,為它賦予明確的值。顯式地定義serialVersionUID有兩種用途:

在某些場合,希望類的不同版本對序列化兼容,因此需要確保類的不同版本具有相同的serialVersionUID;在某些場合,不希望類的不同版本對序列化兼容,因此需要確保類的不同版本具有不同的serialVersionUID。

當你序列化了一個類實例后,希望更改一個字段或添加一個字段,不設置serialVersionUID,所做的任何更改都將導致無法反序化舊有實例,并在反序列化時拋出一個異常。如果你添加了serialVersionUID,在反序列舊有實例時,新添加或更改的字段值將設為初始化值(對象為null,基本類型為相應的初始默認值),字段被刪除將不設置。

相關注意事項:

a)序列化時,只對對象的狀態進行保存,而不管對象的方法;

b)當一個父類實現序列化,子類自動實現序列化,不需要顯式實現Serializable接口;

c)當一個對象的實例變量引用其他對象,序列化該對象時也把引用對象進行序列化;

詳細描述:

序列化的過程就是對象寫入字節流和從字節流中讀取對象。將對象狀態轉換成字節流之后,可以用java.io包中的各種字節流類將其保存到文件中,管道到另一 線程中或通過網絡連接將對象數據發送到另一主機。對象序列化功能非常簡單、強大,在RMI、Socket、JMS、EJB都有應用。對象序列化問題在網絡 編程中并不是最激動人心的課題,但卻相當重要,具有許多實用意義。

對象序列化可以實現分布式對象。主要應用例如:RMI要利用對象序列化運行遠程主機上的服務,就像在本地機上運行對象時一樣。

java 對象序列化不僅保留一個對象的數據,而且遞歸保存對象引用的每個對象的數據。可以將整個對象層次寫入字節流中,可以保存在文件中或在網絡連接上傳遞。利用 對象序列化可以進行對象的“深復制”,即復制對象本身及引用的對象本身。序列化一個對象可能得到整個對象序列。

從上面的敘述中,我們知道了對象序列化是java編程中的必備武器,那么讓我們從基礎開始,好好學習一下它的機制和用法。

java序列化比較簡單,通常不需要編寫保存和恢復對象狀態的定制代碼。實現java.io.Serializable接口的類對象可以轉換成字節流或從 字節流恢復,不需要在類中增加任何代碼。只有極少數情況下才需要定制代碼保存或恢復對象狀態。這里要注意:不是每個類都可序列化,有些類是不能序列化的, 例如涉及線程的類與特定JVM有非常復雜的關系。

序列化機制:

序列化分為兩大部分:序列化和反序列化。序列化是這個過程的第一部分,將數據分解成字節流,以便存儲在文件中或在網絡上傳輸。反序列化就是打開字節流并重構對象。對象序列化不僅要將基本數據類型轉換成字節 表示,有時還要恢復數據。恢復數據要求有恢復數據的對象實例。ObjectOutputStream中的序列化過程與字節流連接,包括對象類型和版本信 息。反序列化時,JVM用頭信息生成對象實例,然后將對象字節流中的數據復制到對象數據成員中。

處理對象流:序列化過程和反序列化過程

java.io包有兩個序列化對象的類。ObjectOutputStream負責將對象寫入字節流,ObjectInputStream從字節流重構對象。

我們先了解ObjectOutputStream類吧。ObjectOutputStream類擴展DataOutput接口。writeObject() 方法是最重要的方法,用于對象序列化。如果對象包含其他對象的引用,則writeObject()方法遞歸序列化這些對象。每個 ObjectOutputStream維護序列化的對象引用表,防止發送同一對象的多個拷貝。(這點很重要)由于writeObject()可以序列化整 組交叉引用的對象,因此同一ObjectOutputStream實例可能不小心被請求序列化同一對象。這時,進行反引用序列化,而不是再次寫入對象字節流。

// 序列化 today’s date 到一個文件中.

FileOutputStream f = new FileOutputStream(“tmp”); //創建一個包含恢復對象(即對象進行反序列化信息)的”tmp”數據文件

ObjectOutputStream s = new ObjectOutputStream(f);

s.writeObject(“Today”); //寫入字符串對象;

s.writeObject(new Date()); //寫入瞬態對象;

s.flush();

現在,讓我們來了解ObjectInputStream這個類。它與ObjectOutputStream相似。它擴展DataInput接口。 ObjectInputStream中的方法鏡像DataInputStream中讀取Java基本數據類型的公開方法。readObject()方法從 字節流中反序列化對象。每次調用readObject()方法都返回流中下一個Object。對象字節流并不傳輸類的字節碼,而是包括類名及其簽名。 readObject()收到對象時,JVM裝入頭中指定的類。如果找不到這個類,則readObject()拋出 ClassNotFoundException,如果需要傳輸對象數據和字節碼,則可以用RMI框架。ObjectInputStream的其余方法用于定制反序列化過程。

//從文件中反序列化 string 對象和 date 對象

FileInputStream in = new FileInputStream(“tmp”);

ObjectInputStream s = new ObjectInputStream(in);

String today = (String)s.readObject(); //恢復對象;

Date date = (Date)s.readObject();

定制序列化過程:

序列化通常可以自動完成,但有時可能要對這個過程進行控制。java可以將類聲明為serializable,但仍可手工控制聲明為static或transient的數據成員。

public class SimpleSerializableClass implements Serializable{

String sToday=”Today:”;

transient Date dtToday=new Date();

}

序 列化時,類的所有數據成員應可序列化除了聲明為transient或static的成員。將變量聲明為transient告訴JVM我們會負責將變元序列 化。將數據成員聲明為transient后,序列化過程就無法將其加進對象字節流中,沒有從transient數據成員發送的數據。后面數據反序列化時, 要重建數據成員(因為它是類定義的一部分),但不包含任何數據,因為這個數據成員不向流中寫入任何數據。記住,對象流不序列化static或 transient。我們的類要用writeObject()與readObject()方法以處理這些數據成員。使用writeObject()與 readObject()方法時,還要注意按寫入的順序讀取這些數據成員。

//重寫writeObject()方法以便處理transient的成員。

public void writeObject(ObjectOutputStream outputStream) throws IOException{

outputStream.defaultWriteObject();//使定制的writeObject()方法可以利用自動序列化中內置的邏輯。

outputStream.writeObject(oSocket.getInetAddress());

outputStream.writeInt(oSocket.getPort());

}

//重寫readObject()方法以便接收transient的成員。

private void readObject(ObjectInputStream inputStream) throws IOException,ClassNotFoundException{

inputStream.defaultReadObject();//defaultReadObject()補充自動序列化

InetAddress oAddress=(InetAddress)inputStream.readObject();

int iPort =inputStream.readInt();

oSocket = new Socket(oAddress,iPort);

iID=getID();

dtToday =new Date();

}

完全定制序列化過程:

如果一個類要完全負責自己的序列化,則實現Externalizable接口而不是Serializable接口。Externalizable接口定義包 括兩個方法writeExternal()與readExternal()。利用這些方法可以控制對象數據成員如何寫入字節流.類實現 Externalizable時,頭寫入對象流中,然后類完全負責序列化和恢復數據成員,除了頭以外,根本沒有自動序列化。這里要注意了。聲明類實現 Externalizable接口會有重大的安全風險。writeExternal()與readExternal()方法聲明為public,惡意類可 以用這些方法讀取和寫入對象數據。如果對象包含敏感信息,則要格外小心。這包括使用安全套接或加密整個字節流。到此為至,我們學習了序列化的基礎部分知識。

以下來源于J2EE API:

對象的默認序列化機制寫入的內容是:對象的類,類簽名,以及非瞬態和非靜態字段的值。其他對象的引用(瞬態和靜態字段除外)也會導致寫入那些對象。可使用引用共享機制對單個對象的多個引用進行編碼,這樣即可將對象的圖形還原為最初寫入它們時的形狀。

例如,要寫入可通過 ObjectInputStream 中的示例讀取的對象,請執行以下操作:

FileOutputStream fos = new FileOutputStream(“t.tmp”);

ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeInt(12345);

oos.writeObject(“Today”);

oos.writeObject(new Date());

oos.close();

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

private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException;

private void writeObject(java.io.ObjectOutputStream stream) throws IOException;

writeObject 方法負責寫入特定類的對象狀態,以便相應的 readObject 方法可以還原它。該方法本身不必與屬于對象的超類或子類的狀態有關。狀態是通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數據類型的方法將各個字段寫入 ObjectOutputStream 來保存的。

序列化操作不寫出沒有實現 java.io.Serializable 接口的任何對象的字段。不可序列化的 Object 的子類可以是可序列化的。在此情況下,不可序列化的類必須有一個無參數構造方法,以便允許初始化其字段。在此情況下,子類負責保存和還原不可序列化的類的 狀態。經常出現的情況是,該類的字段是可訪問的(public、package 或 protected),或者存在可用來還原狀態的 get 和 set 方法。

實現 writeObject 和 readObject 方法可以阻止對象的序列化,這時拋出 NotSerializableException。ObjectOutputStream 導致發生異常并中止序列化進程。

實 現 Externalizable 接口允許對象假定可以完全控制對象的序列化形式的內容和格式。調用 Externalizable 接口的方法(writeExternal 和 readExternal)來保存和恢復對象的狀態。通過類實現時,它們可以使用 ObjectOutput 和 ObjectInput 的所有方法讀寫它們自己的狀態。對象負責處理出現的任何版本控制。

Enum 常量的序列化不同于普通的 serializable 或 externalizable 對象。enum 常量的序列化形式只包含其名稱;常量的字段值不被傳送。為了序列化 enum 常量,ObjectOutputStream 需要寫入由常量的名稱方法返回的字符串。與其他 serializable 或 externalizable 對象一樣,enum 常量可以作為序列化流中后續出現的 back 引用的目標。用于序列化 enum 常量的進程不可定制;在序列化期間,由 enum 類型定義的所有類特定的 writeObject 和 writeReplace 方法都將被忽略。類似地,任何 serialPersistentFields 或 serialVersionUID 字段聲明也將被忽略,所有 enum 類型都有一個 0L 的固定的 serialVersionUID。

基本數據(不包括 serializable 字段和 externalizable 數據)以塊數據記錄的形式寫入 ObjectOutputStream 中。塊數據記錄由頭部和數據組成。塊數據部分包括標記和跟在部分后面的字節數。連續的基本寫入數據被合并在一個塊數據記錄中。塊數據記錄的分塊因子為 1024 字節。每個塊數據記錄都將填滿 1024 字節,或者在終止塊數據模式時被寫入。調用 ObjectOutputStream 方法 writeObject、defaultWriteObject 和 writeFields 最初只是終止所有現有塊數據記錄。

JSON化

更多信息請查看IT技術專欄

更多信息請查看網絡編程
易賢網手機網站地址:Java序列化(Serializable)與反序列化
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
香蕉免费一区二区三区在线观看| 久久综合一区二区| 国产精品二区在线观看| 久久久蜜桃精品| 久久免费黄色| 欧美精品乱人伦久久久久久| 欧美日韩日韩| 国产色爱av资源综合区| 黄色精品一二区| 亚洲免费中文字幕| 亚洲图片欧美午夜| 久久动漫亚洲| 欧美日韩精品一区视频 | 亚洲自拍16p| 久热综合在线亚洲精品| 欧美激情国产高清| 国产精品成人观看视频国产奇米| 国产欧美在线| 99国产精品视频免费观看一公开| 午夜亚洲影视| 欧美午夜不卡在线观看免费 | 国产精品一二三四| 亚洲国产美女精品久久久久∴| 制服丝袜亚洲播放| 久久精品国产亚洲aⅴ| 欧美激情无毛| 国产伦一区二区三区色一情| 亚洲精品在线观看视频| 欧美一区二区三区四区在线观看| 欧美区在线播放| 亚洲三级视频| 欧美国产专区| 亚洲国产精品一区二区www| 欧美一级成年大片在线观看| 欧美日韩午夜剧场| 99国产精品久久| 欧美日韩一区二区三区在线观看免 | 久久精品一本| 欧美激情综合五月色丁香小说| 国产视频一区二区在线观看| 亚洲午夜久久久| 国产精品美女久久久久av超清| 欧美一区二区三区男人的天堂 | 久久综合精品国产一区二区三区| 欧美成人一区在线| 亚洲黄色在线| 欧美乱妇高清无乱码| 国产视频综合在线| 久久国产日韩欧美| 亚洲国产欧美日韩另类综合| 狼人社综合社区| 99re热这里只有精品视频| 欧美—级高清免费播放| 久久精品视频一| 欧美性大战久久久久久久| 欧美1区2区| 国产精品一区一区| 国产精品美女主播| 久久综合久久综合久久| 国产精品久久久久久户外露出| 亚洲欧洲日产国产网站| 国产精品成人一区二区三区吃奶 | 欧美人与性动交cc0o| 久久露脸国产精品| 久久精品视频在线观看| 欧美一级视频免费在线观看| 亚洲第一久久影院| 老司机凹凸av亚洲导航| 一区二区av| 亚洲国产精品久久久久| 国产精品成人v| 欧美视频1区| 欧美国产高潮xxxx1819| 欧美不卡一区| 夜夜爽www精品| 亚洲国产婷婷香蕉久久久久久99| 国产精品裸体一区二区三区| 欧美黄色aaaa| 欧美激情免费观看| 欧美a级片一区| 欧美久久影院| 国产精品毛片a∨一区二区三区| 欧美激情综合五月色丁香| 一区二区国产日产| 一本色道久久综合狠狠躁篇怎么玩| 亚洲欧洲一区二区天堂久久| 亚洲精品免费在线播放| 99综合精品| 欧美亚洲一区二区在线| 久久精品国产欧美亚洲人人爽| 午夜久久美女| 老司机凹凸av亚洲导航| 欧美激情一区| 国产欧美韩国高清| 在线免费观看欧美| 日韩亚洲精品电影| 午夜视频在线观看一区二区三区 | 一个色综合av| 亚洲视频一区在线观看| 久久精品视频免费观看| 欧美日韩一级视频| 国产欧美日韩另类一区| 国产一区91精品张津瑜| 亚洲国产一区在线| 亚洲深夜福利| 欧美国产精品中文字幕| 欧美亚男人的天堂| 国产一区二区三区久久久久久久久| 久久国产一区二区三区| 美女福利精品视频| 国产精品色网| 一区二区激情视频| 欧美高清视频一区二区三区在线观看 | 亚洲电影av| 欧美在线影院在线视频| 国产农村妇女精品一区二区| 亚洲一区二区三区在线看| 欧美精品三区| 亚洲黄色天堂| 欧美激情bt| 国产精品福利在线观看| 在线精品视频一区二区| 久久久视频精品| 一区二区三区无毛| 久久久天天操| 亚洲精品一区久久久久久| 免费在线亚洲欧美| 日韩午夜精品视频| 午夜国产精品视频免费体验区| 国产精品欧美日韩| 久久精品一区二区三区不卡牛牛| 狠狠色伊人亚洲综合成人| 久久精品国产成人| 亚洲黄色影院| 国产日韩欧美麻豆| 欧美极品在线视频| 欧美在线免费观看视频| 亚洲国产毛片完整版| 国产精品视频导航| 欧美国产精品一区| 久久国产精品一区二区三区| 亚洲精品久久久久久久久| 国产精品日韩欧美| 香蕉av777xxx色综合一区| 国产亚洲精品一区二555| 欧美日韩一区在线观看视频| 久久精品欧美| 校园激情久久| 亚洲精品美女在线观看| 国产女优一区| 欧美三级电影大全| 麻豆成人在线观看| 国产一区二区三区日韩| 久久综合综合久久综合| 日韩视频免费观看高清完整版| 欧美日韩色一区| 久久综合给合久久狠狠狠97色69| 99综合电影在线视频| 影音先锋欧美精品| 国产精品免费看| 欧美国产日本| 久久精品国产69国产精品亚洲| 99视频精品免费观看| 韩日视频一区| 狠狠干综合网| 欧美日韩mp4| 欧美制服丝袜第一页| 一区二区三区国产盗摄| 一区在线播放视频| 国产日韩欧美在线播放不卡| 欧美日韩国产123| 欧美国产精品v| 欧美超级免费视 在线| 久久一本综合频道| 国产在线精品成人一区二区三区| 免费观看30秒视频久久| 久久福利资源站| 午夜国产欧美理论在线播放| 一本综合久久| 亚洲人成7777| 亚洲国产精品99久久久久久久久| 国产一区999| 亚洲第一区在线观看| 国产综合久久久久久| 国内精品国产成人| 久久精品91| 久久精品99无色码中文字幕| 久久精品综合| 亚洲区国产区| 久久久久青草大香线综合精品| 欧美日韩午夜| 一区二区三区四区五区精品| 欧美一区二视频在线免费观看| 欧美日韩一卡| 中日韩午夜理伦电影免费| 欧美激情国产日韩| 中文国产成人精品| 国产手机视频精品| 久久久久国产精品www| 亚洲国产高清一区二区三区|