官术网_书友最值得收藏!

2.4.1 保存和加載序列化對象

為了保存對象數據,首先需要打開一個ObjectOutputStream對象:

現在,為了保存對象,可以直接使用ObjectOutputStream的writeObject方法,如下所示:

為了將這些對象讀回,首先需要獲得一個ObjectInputStream對象:

然后,用readObject方法以這些對象被寫出時的順序獲得它們:

但是,對希望在對象輸出流中存儲或從對象輸入流中恢復的所有類都應進行一下修改,這些類必須實現Serializable接口:

Serializable接口沒有任何方法,因此你不需要對這些類做任何改動。在這一點上,它與在卷Ⅰ第6章中討論過的Cloneable接口很相似。但是,為了使類可克隆,你仍舊需要覆蓋Object類中的clone方法,而為了使類可序列化,你不需要做任何事。

注意:你只有在寫出對象時才能用writeObject/readObject方法,對于基本類型值,你需要使用諸如writeInt/readInt或writeDouble/readDouble這樣的方法。(對象流類都實現了DataInput/DataOutput接口。)

在幕后,是ObjectOutputStream在瀏覽對象的所有域,并存儲它們的內容。例如,當寫出一個Employee對象時,其名字、日期和薪水域都會被寫出到輸出流中。

但是,有一種重要的情況需要考慮:當一個對象被多個對象共享,作為它們各自狀態的一部分時,會發生什么呢?

為了說明這個問題,我們對Manager類稍微做些修改,假設每個經理都有一個秘書:

現在每個Manager對象都包含一個表示秘書的Employee對象的引用,當然,兩個經理可以共用一個秘書,正如圖2-5和下面的代碼所示的那樣:

保存這樣的對象網絡是一種挑戰,在這里我們當然不能去保存和恢復秘書對象的內存地址,因為當對象被重新加載時,它可能占據的是與原來完全不同的內存地址。

與此不同的是,每個對象都是用一個序列號(serial number)保存的,這就是這種機制之所以稱為對象序列化的原因。下面是其算法:

·對你遇到的每一個對象引用都關聯一個序列號(如圖2-6所示)。

·對于每個對象,當第一次遇到時,保存其對象數據到輸出流中。

·如果某個對象之前已經被保存過,那么只寫出“與之前保存過的序列號為x的對象相同”。

圖2-5 兩個經理可以共用一個共有的雇員

圖2-6 一個對象序列化的實例

在讀回對象時,整個過程是反過來的。

·對于對象輸入流中的對象,在第一次遇到其序列號時,構建它,并使用流中數據來初始化它,然后記錄這個順序號和新對象之間的關聯。

·當遇到“與之前保存過的序列號為x的對象相同”標記時,獲取與這個順序號相關聯的對象引用。

注意:在本章中,我們使用序列化將對象集合保存到磁盤文件中,并按照它們被存儲的樣子獲取它們。序列化的另一種非常重要的應用是通過網絡將對象集合傳送到另一臺計算機上。正如在文件中保存原生的內存地址毫無意義一樣,這些地址對于在不同的處理器之間的通信也是毫無意義的。因為序列化用序列號代替了內存地址,所以它允許將對象集合從一臺機器傳送到另一臺機器。

程序清單2-3是保存和重新加載Employee和Manager對象網絡的代碼(有些對象共享相同的表示秘書的雇員)。注意,秘書對象在重新加載之后是唯一的,當newStaff[1]被恢復時,它會反映到經理們的secretary域中。

程序清單2-3 objectStream/ObjectStreamTest.java

java.io.ObjectOutputStream 1.1

·ObjectOutputStream(OutputStream out)

創建一個ObjectOutputStream使得你可以將對象寫出到指定的OutputStream。

·void writeObject(Object obj)

寫出指定的對象到ObjectOutputStream,這個方法將存儲指定對象的類、類的簽名以及這個類及其超類中所有非靜態和非瞬時的域的值。

java.io.ObjectInputStream 1.1

·ObjectInputStream(InputStream in)

創建一個ObjectInputStream用于從指定的InputStream中讀回對象信息。

·Object readObject()

從ObjectInputStream中讀入一個對象。特別是,這個方法會讀回對象的類、類的簽名以及這個類及其超類中所有非靜態和非瞬時的域的值。它執行的反序列化允許恢復多個對象引用。

主站蜘蛛池模板: 宝山区| 曲水县| 准格尔旗| 青田县| 沁源县| 拉萨市| 定西市| 视频| 延津县| 和政县| 宝坻区| 绥德县| 苗栗市| 海城市| 太仓市| 北票市| 阳朔县| 正安县| 三台县| 瑞丽市| 甘谷县| 昭苏县| 黄冈市| 聊城市| 栾川县| 富裕县| 双鸭山市| 南通市| 天镇县| 西和县| 颍上县| 北辰区| 汕尾市| 扬中市| 库尔勒市| 西充县| 上饶县| 渝北区| 萝北县| 黄浦区| 西城区|