Java™ 教程(對象流)

對象流

正如數據流支持原始數據類型的I/O同樣,對象流也支持對象的I/O,大多數(但不是所有)標準類支持其對象的序列化,那些是實現標記接口Serializable的。html

對象流類是ObjectInputStreamObjectOutputStream,這些類實現ObjectInputObjectOutput,它們是DataInputDataOutput的子接口。這意味着數據流中涵蓋的全部原始數據I/O方法也在對象流中實現,所以,對象流能夠包含原始值和對象值的混合。ObjectStreams示例說明了這一點,ObjectStreams建立與DataStreams相同的應用程序,並進行了一些更改,首先,價格如今是BigDecimal對象,以更好地表明小數值,其次,將Calendar對象寫入數據文件,指示發票日期。java

若是readObject()沒有返回預期的對象類型,則嘗試將其強制轉換爲正確的類型可能會拋出ClassNotFoundException,在這個簡單的例子中,這不可能發生,所以咱們不會嘗試捕獲異常,相反,咱們經過向main方法的throws子句添加ClassNotFoundException來通知編譯器咱們已經意識到了這個問題。git

複雜對象的輸出和輸入

writeObjectreadObject方法易於使用,但它們包含一些很是複雜的對象管理邏輯,這對像Calendar這樣的類來講並不重要,它只封裝了原始值,可是許多對象包含對其餘對象的引用,若是readObject是要從流重建一個對象,它必須可以重建原始對象所引用的全部對象,這些附加對象可能有本身的引用,依此類推。在這種狀況下,writeObject遍歷整個對象引用網絡,並將該網絡中的全部對象寫入流,所以,對writeObject的單個調用可能致使將大量對象寫入流。github

下圖演示了這一點,其中調用writeObject來寫入名爲a的單個對象,該對象包含對象bc的引用,而b包含對de的引用,調用writeobject(a)不只寫入a,並且寫入重建a所需的全部對象,所以該網絡中的其餘四個對象也被寫入。當readObject讀回a時,也會讀回其餘四個對象,並保留全部原始對象引用。segmentfault

io-trav.gif

你可能想知道若是同一個流上的兩個對象都包含對單個對象的引用會發生什麼,當他們被回讀時,他們都會引用一個對象嗎?答案是確定的。一個流只能包含一個對象的副本,儘管它能夠包含對該對象的任意數量的引用,所以,若是你明確地將對象寫入流兩次,那麼你實際上只寫入了兩次引用,例如,若是如下代碼將對象ob寫入流兩次:api

Object ob = new Object();
out.writeObject(ob);
out.writeObject(ob);

每一個writeObject都必須與readObject匹配,所以讀迴流的代碼將以下所示:網絡

Object ob1 = in.readObject();
Object ob2 = in.readObject();

這產生兩個變量ob1ob2,它們是對單個對象的引用。oracle

可是,若是將單個對象寫入兩個不一樣的流,則會有效地複製它 — 讀取兩個流的單個程序將看到兩個不一樣的對象。spa


上一篇:數據流

相關文章
相關標籤/搜索