對象序列化

Java的對象序列化(Object Serialization)將那些實現了 Serializable接口的對象轉換
成一個字節序列,並可以在以後將這個字節序列完全恢復爲原來的對象。這一過程甚至可通
過網絡進行。這意味着序列化機制能自動彌補不同操作系統之間的差異。也就是說,可以在
運行 Windows 系統的計算機上創建一個對象,將其序列化,通過網絡將它發送給一臺運行

Unix 系統的計算機,然後在那裏準確地重新組裝,而你卻不必擔心數據在不同機器上的表
示會不同,也不必關心字節的順序或者其他任何細節。
就其本身來說,對象的序列化是非常有趣的,因爲利用它可以實現“輕量級持久化
(lightweight persistence)”。“持久化”意味着一個對象的生存週期並不取決於程序是否
正在執行;它可以生存於程序的調用之間。通過將一個序列化對象寫入磁盤,然後在重新調
用程序時恢復該對象,就能夠實現持久化的效果。之所以稱其爲“輕量級”,是因爲不能用某
種“persistent”(持久)關鍵字來簡單地定義一個對象,並讓系統自動維護其他細節問題(盡
管將來有可能實現)。相反,對象必須在程序中顯式地序列化和重組。如果需要一個更嚴格
的持久化機制,可以考慮使用 Java數據對象(JDO)或者像 Hibernate之類的工具

 

對 Java Beans來說對象的序列化也是必需的,可參看第 14章。使用一個 Bean 時,一般
情況下是在設計階段對它的狀態信息進行配置。這種狀態信息必須保存下來,並在程序啓動
以後,進行恢復;具體工作由對象序列化完成。
只要對象實現了 Serializable接口(該接口僅是一個標記接口,不包括任何方法),對象的
序列化處理就會非常簡單。當序列化的概念被加入到語言中時,許多標準庫類都發生了改變,
以便能夠使之序列化——其中包括所有原始數據類型的封裝器、所有容器類以及許多其他的
東西。甚至 Class 對象也可以被序列化。
爲了序列化一個對象,首先要創建某些 OutputStream對象,然後將其封裝在一個
ObjectOutputStream對象內。這時,只需調用 writeObject()即可將對象序列化,並將
其發送給 OutputStream。要將一個序列重組爲一個對象,需要將一個 InputStream封
裝在 ObjectInputStream內,然後調用 readObject()。和往常一樣,我們最後獲得的是
指向一個向上轉型爲 Object 的句柄,所以必須向下轉型,以便能夠直接對其進行設置。

 

對象序列化特別“聰明”的一個地方是它不僅保存了對象的“全景圖”,而且能追蹤對象內包含
的所有引用並保存那些對象;接着又能對每個這樣的對象內包含的引用進行追蹤;以此類推。
這種情況有時被稱爲“對象網”,單個對象可與之建立連接,而且它還包含了對象的引用數組
以和成員對象。如果必須保持一套自己的對象序列化機制,那麼維護那些可追蹤到所有鏈接
的代碼可能會顯得非常麻煩。然而,由於 Java的對象序列化似乎找不出什麼缺點,所以請
儘量不要自己動手,讓它用優化的算法自動維護整個對象網。下面這個例子通過對鏈接的對
象生成一個“Worm”(蠕蟲)對序列化機制進行了測試。每個對象都與 Worm中的下一段
鏈接,同時又與屬於不同類(Data)的對象引用數組鏈接:

 

Java I/O流類庫的確能滿足我們的基本需求:我們可以通過控制檯、文件、內存塊甚至因
特網進行讀寫。通過繼承,我們可以創建新類型的 input和 output對象。並且通過重新定
義 toString()方法,我們甚至可以爲流接受的對象類型進行簡單擴充。當我們向期望收
到一個字符串的方法傳送一個對象時,會自動調用 toString()方法。(這是 Java有限的
自動類型轉換功能。)

 

在 I/O 流類庫的文檔和設計中,仍留有一些沒有解決的問題。例如,當我們打開一個文件
以便輸出時,我們可以指定一旦試圖覆蓋該文件就拋出一個異常——有的編程系統允許我們
自行指定想要打開的輸出文件,只要它尚不存在。在 Java中,我們似乎應該使用一個 File
對象來判斷某個文件是否存在,因爲如果我們以FileOutputStream或者FileWriter打開,
那麼它肯定會被覆蓋。
I/O 流類庫使我們喜憂參半。它確實能做許多事情,而且具有可移植性。但是如果我們沒有
理解修飾器模式,那麼這種設計就不是很直覺,因此,在學習和傳授它的過程中,需要額外
的開銷。而且它並不完善;例如我應該可以不必去寫像 TextFile 這樣的應用,並且它沒有
任何對輸出格式化的種類的支持,而事實上其他所有語言的 I/O 包都提供這種支持。
然而,一旦我們理解了修飾器模式,並開始在某些情況下使用該類庫以利用其能夠提供的靈
活性,那麼你就開始從這個設計中受益了。到那個時候,爲此額外多寫幾行代碼的開銷應該
不至於使人覺得太麻煩。
如果你在本章沒有發現想要找尋的東西(這裏僅僅是一個初步介紹,其涵蓋面並不全面),
可以在《Java I/O》中找到更深入的論述, Elliotte Rusty Harold 著(O’Reilly, 1999)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章