對(duì)象流
正如數(shù)據(jù)流支持原始數(shù)據(jù)類型的I/O一樣,對(duì)象流也支持對(duì)象的I/O,大多數(shù)(但不是全部)標(biāo)準(zhǔn)類支持其對(duì)象的序列化,那些是實(shí)現(xiàn)標(biāo)記接口Serializable的。
對(duì)象流類是ObjectInputStream和ObjectOutputStream,這些類實(shí)現(xiàn)ObjectInput和ObjectOutput,它們是DataInput和DataOutput的子接口。這意味著數(shù)據(jù)流中涵蓋的所有原始數(shù)據(jù)I/O方法也在對(duì)象流中實(shí)現(xiàn),因此,對(duì)象流可以包含原始值和對(duì)象值的混合。ObjectStreams示例說明了這一點(diǎn),ObjectStreams創(chuàng)建與DataStreams相同的應(yīng)用程序,并進(jìn)行了一些更改,首先,價(jià)格現(xiàn)在是BigDecimal對(duì)象,以更好地代表小數(shù)值,其次,將Calendar對(duì)象寫入數(shù)據(jù)文件,指示發(fā)票日期。
如果readObject()沒有返回預(yù)期的對(duì)象類型,則嘗試將其強(qiáng)制轉(zhuǎn)換為正確的類型可能會(huì)拋出ClassNotFoundException,在這個(gè)簡單的例子中,這不可能發(fā)生,因此我們不會(huì)嘗試捕獲異常,相反,我們通過向main方法的throws子句添加ClassNotFoundException來通知編譯器我們已經(jīng)意識(shí)到了這個(gè)問題。
復(fù)雜對(duì)象的輸出和輸入writeObject和readObject方法易于使用,但它們包含一些非常復(fù)雜的對(duì)象管理邏輯,這對(duì)像Calendar這樣的類來說并不重要,它只封裝了原始值,但是許多對(duì)象包含對(duì)其他對(duì)象的引用,如果readObject是要從流重建一個(gè)對(duì)象,它必須能夠重建原始對(duì)象所引用的所有對(duì)象,這些附加對(duì)象可能有自己的引用,依此類推。在這種情況下,writeObject遍歷整個(gè)對(duì)象引用網(wǎng)絡(luò),并將該網(wǎng)絡(luò)中的所有對(duì)象寫入流,因此,對(duì)writeObject的單個(gè)調(diào)用可能導(dǎo)致將大量對(duì)象寫入流。
下圖演示了這一點(diǎn),其中調(diào)用writeObject來寫入名為a的單個(gè)對(duì)象,該對(duì)象包含對(duì)象b和c的引用,而b包含對(duì)d和e的引用,調(diào)用writeobject(a)不僅寫入a,而且寫入重建a所需的所有對(duì)象,因此該網(wǎng)絡(luò)中的其他四個(gè)對(duì)象也被寫入。當(dāng)readObject讀回a時(shí),也會(huì)讀回其他四個(gè)對(duì)象,并保留所有原始對(duì)象引用。
你可能想知道如果同一個(gè)流上的兩個(gè)對(duì)象都包含對(duì)單個(gè)對(duì)象的引用會(huì)發(fā)生什么,當(dāng)他們被回讀時(shí),他們都會(huì)引用一個(gè)對(duì)象嗎?答案是肯定的。一個(gè)流只能包含一個(gè)對(duì)象的副本,盡管它可以包含對(duì)該對(duì)象的任意數(shù)量的引用,因此,如果你明確地將對(duì)象寫入流兩次,那么你實(shí)際上只寫入了兩次引用,例如,如果以下代碼將對(duì)象ob寫入流兩次:
Object ob = new Object(); out.writeObject(ob); out.writeObject(ob);
每個(gè)writeObject都必須與readObject匹配,因此讀回流的代碼將如下所示:
Object ob1 = in.readObject(); Object ob2 = in.readObject();
這產(chǎn)生兩個(gè)變量ob1和ob2,它們是對(duì)單個(gè)對(duì)象的引用。
但是,如果將單個(gè)對(duì)象寫入兩個(gè)不同的流,則會(huì)有效地復(fù)制它 — 讀取兩個(gè)流的單個(gè)程序?qū)⒖吹絻蓚€(gè)不同的對(duì)象。
上一篇:數(shù)據(jù)流文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/72988.html
Java? 教程 Java教程是為JDK 8編寫的,本頁面中描述的示例和實(shí)踐沒有利用在后續(xù)版本中引入的改進(jìn)。 Java教程是希望使用Java編程語言創(chuàng)建應(yīng)用程序的程序員的實(shí)用指南,其中包括數(shù)百個(gè)完整的工作示例和數(shù)十個(gè)課程,相關(guān)課程組被組織成教程。 覆蓋基礎(chǔ)知識(shí)的路徑 這些教程以書籍的形式提供,如Java教程,第六版,前往Amazon.com購買。 入門 介紹Java技術(shù)和安裝Java開發(fā)軟件并使用...
命令行I/O 程序通常從命令行運(yùn)行,并在命令行環(huán)境中與用戶交互,Java平臺(tái)以兩種方式支持這種交互:通過標(biāo)準(zhǔn)流和控制臺(tái)。 標(biāo)準(zhǔn)流 標(biāo)準(zhǔn)流是許多操作系統(tǒng)的一個(gè)特性,默認(rèn)情況下,它們從鍵盤讀取輸入并將輸出寫入顯示器,它們還支持文件和程序之間的I/O,但該功能由命令行解釋器控制,而不是程序。 Java平臺(tái)支持三種標(biāo)準(zhǔn)流:標(biāo)準(zhǔn)輸入,可通過System.in訪問;標(biāo)準(zhǔn)輸出,可通過System.out訪問;和...
緩沖流 到目前為止,我們看到的大多數(shù)示例都使用無緩沖的I/O,這意味著每個(gè)讀取或?qū)懭胝?qǐng)求都由底層操作系統(tǒng)直接處理,這可以使程序效率低得多,因?yàn)槊總€(gè)這樣的請(qǐng)求通常觸發(fā)磁盤訪問、網(wǎng)絡(luò)活動(dòng)或一些相對(duì)昂貴的其他操作。 為了減少這種開銷,Java平臺(tái)實(shí)現(xiàn)了緩沖的I/O流,緩沖輸入流從稱為緩沖區(qū)的內(nèi)存區(qū)讀取數(shù)據(jù),僅當(dāng)緩沖區(qū)為空時(shí)才調(diào)用原生輸入API,類似地,緩沖輸出流將數(shù)據(jù)寫入緩沖區(qū),并且僅在緩沖區(qū)已滿時(shí)才調(diào)...
數(shù)據(jù)流 數(shù)據(jù)流支持原始數(shù)據(jù)類型值(boolean、char、byte、short、int、long、float和double)以及String值的二進(jìn)制I/O,所有數(shù)據(jù)流都實(shí)現(xiàn)DataInput接口或DataOutput接口,本節(jié)重點(diǎn)介紹這些接口最廣泛使用的實(shí)現(xiàn),DataInputStream和DataOutputStream。 DataStreams示例通過寫出一組數(shù)據(jù)記錄,然后再次讀取它們來演...
格式化流 實(shí)現(xiàn)格式化的流對(duì)象是PrintWriter(字符流類)或PrintStream(字節(jié)流類)的實(shí)例。 你可能需要的唯一PrintStream對(duì)象是System.out和System.err(有關(guān)這些對(duì)象的更多信息,請(qǐng)參閱命令行中的I/O),當(dāng)你需要?jiǎng)?chuàng)建格式化的輸出流時(shí),請(qǐng)實(shí)例化PrintWriter,而不是PrintStream。 與所有字節(jié)和字符流對(duì)象一樣,PrintStream和Pri...
閱讀 1944·2021-11-17 09:33
閱讀 6573·2021-10-12 10:20
閱讀 2386·2021-09-22 15:50
閱讀 1862·2021-09-22 15:10
閱讀 816·2021-09-10 10:51
閱讀 726·2021-09-10 10:50
閱讀 3175·2021-08-11 11:19
閱讀 1839·2019-08-30 15:55