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

Java序列化(Serializable)與反序列化
來源:易賢網 閱讀:994 次 日期:2015-04-09 17:24:07
溫馨提示:易賢網小編為您整理了“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:

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

例如,要寫入可通過 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 最初只是終止所有現有塊數據記錄。

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

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

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

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
雨宫琴音一区二区在线| 国产欧美亚洲日本| 久久人人爽人人爽爽久久| 激情综合五月天| 国产乱人伦精品一区二区 | 99re6热在线精品视频播放速度| 国产欧美日韩在线观看| 国产精品v亚洲精品v日韩精品 | 国产精品午夜在线观看| 欧美日韩国产91| 欧美黑人在线观看| 欧美激情无毛| 欧美日韩成人综合天天影院| 欧美激情欧美激情在线五月| 欧美华人在线视频| 欧美激情日韩| 欧美视频在线观看一区二区| 欧美视频一区二区三区…| 欧美无砖砖区免费| 国产精品理论片| 国产日韩在线视频| 狠狠色噜噜狠狠色综合久| 伊人激情综合| 日韩手机在线导航| 午夜精品www| 久久亚洲色图| 欧美黄色精品| 欧美午夜一区二区| 国产九九精品视频| 一区二区三区我不卡| 最新日韩精品| 亚洲欧美一区二区三区在线| 久久精品在线观看| 欧美v亚洲v综合ⅴ国产v| 欧美日韩成人激情| 国产精品视频免费一区| 激情懂色av一区av二区av| 亚洲激情在线激情| 亚洲一区二区三区免费观看| 新片速递亚洲合集欧美合集| 久久在线视频| 欧美日韩一区二区三区在线| 国产日韩欧美亚洲一区| 精品成人在线| 亚洲一本大道在线| 久久久精品网| 欧美三级中文字幕在线观看| 国产亚洲亚洲| 99re热精品| 久久久国产精彩视频美女艺术照福利| 牛夜精品久久久久久久99黑人 | 午夜精品久久久久久久99樱桃| 欧美在线网址| 欧美日韩精品一区二区三区| 国产一区二区三区日韩| 日韩一级免费| 免费国产一区二区| 国产精品欧美日韩| 亚洲美女诱惑| 牛牛影视久久网| 国内外成人免费激情在线视频| 中文无字幕一区二区三区| 久久天堂国产精品| 国产欧美日韩精品在线| 99re8这里有精品热视频免费 | 欧美日韩一区二区视频在线观看| 国产日韩欧美成人| 一本大道久久a久久精二百| 看欧美日韩国产| 国产欧美日韩精品专区| 在线亚洲自拍| 欧美日韩国产123| 亚洲福利视频免费观看| 久久精品国产亚洲一区二区三区 | 国产精品亚洲精品| 亚洲美女啪啪| 欧美成人在线网站| 在线电影国产精品| 久久精品道一区二区三区| 国产精品一二一区| 亚洲午夜精品网| 欧美日韩一区在线观看| 亚洲精品久久久久久一区二区| 久久这里有精品视频| 国产真实精品久久二三区| 欧美在线三区| 国产一区二区三区免费不卡| 午夜精品福利一区二区三区av| 欧美午夜不卡| 亚洲性感美女99在线| 国产精品久久久久国产精品日日| 99国产精品久久久| 欧美日韩国产一区| 一区二区三区|亚洲午夜| 欧美日韩在线亚洲一区蜜芽| 中文欧美字幕免费| 国产精品久久久久久久久免费樱桃| 亚洲午夜国产成人av电影男同| 欧美视频在线观看 亚洲欧| 亚洲图中文字幕| 国产九色精品成人porny| 欧美一区观看| 亚洲国产成人精品久久久国产成人一区 | 国产精品麻豆va在线播放| 亚洲一区欧美| 国产乱码精品一区二区三区忘忧草| 亚洲欧美第一页| 国产一区二区无遮挡| 久久综合免费视频影院| 最新日韩在线| 国产精品久久久久久妇女6080| 午夜久久一区| 亚洲国产成人精品女人久久久| 欧美人成在线视频| 亚洲欧美中文日韩在线| 韩国av一区二区三区| 欧美成人久久| 亚洲无线视频| 曰本成人黄色| 国产精品成人一区二区三区吃奶| 午夜精品视频一区| 亚洲激情成人| 国产精品一区一区三区| 农村妇女精品| 在线免费日韩片| 一区二区三区四区五区在线| 国产精品狠色婷| 久久久国产91| 亚洲精品日韩一| 国产精品一区二区女厕厕| 久久一区二区三区国产精品| 亚洲精品视频在线| 国产日韩欧美三级| 欧美精品乱码久久久久久按摩| 在线中文字幕日韩| 狠狠久久综合婷婷不卡| 欧美日韩性生活视频| 久久九九精品99国产精品| 99精品视频免费| 好看的日韩视频| 国产日韩欧美中文在线播放| 欧美sm视频| 久久激情中文| 亚洲天堂av在线免费| 亚洲高清免费在线| 国产精品一二一区| 欧美高清视频在线播放| 欧美一级艳片视频免费观看| 99re6这里只有精品| 精品白丝av| 国产精品女主播| 欧美日韩免费网站| 麻豆精品国产91久久久久久| 午夜精品久久久久久久久久久久久| 亚洲精品在线电影| 在线观看精品视频| 国产精品一区一区三区| 欧美日韩一级黄| 欧美夫妇交换俱乐部在线观看| 久久爱另类一区二区小说| 亚洲少妇在线| 亚洲精品三级| 亚洲精品免费在线| 亚洲二区在线视频| 国内外成人免费视频| 国产精品一区二区久激情瑜伽| 欧美成人免费一级人片100| 久久精品一区二区国产| 亚洲香蕉网站| 日韩一区二区精品葵司在线| 亚洲九九爱视频| 亚洲九九爱视频| 亚洲免费观看高清完整版在线观看熊| 在线精品国产欧美| 亚洲大片免费看| 在线观看亚洲专区| 精品99一区二区| 在线欧美视频| 亚洲人成在线观看| 亚洲精品国产欧美| 日韩视频永久免费| 日韩视频免费在线| 亚洲最新合集| 亚洲一区免费| 欧美亚洲在线视频| 久久精品论坛| 美女爽到呻吟久久久久| 免费在线观看成人av| 欧美黄色网络| 欧美日韩三区四区| 国产精品国产三级国产aⅴ9色| 欧美午夜免费影院| 国产精品系列在线播放| 国产在线观看一区| 一色屋精品亚洲香蕉网站| 久久精品麻豆| 欧美成人精品一区| 欧美色区777第一页| 国产伦精品一区二区三区视频黑人| 国产精品国产馆在线真实露脸|