友情提醒:軟件水平與資格考試考試在即,以往的通過率一般為20%。天極網校開通了初級至高級軟考輔導,采取網上與網下的多媒體教學方式,集中火力輔導學員攻克下午試題,共同實現通過率為60%的目標,成績優異者可獲3000元大獎。詳情請見:http://training.yesky.com/topic/softtopic/INDEX.HTM |
使用JavaTM遠程方法調用(RMI),可以很方便地開發分布式的基于對象的應用程序。RMI的簡單性,是由網絡通信的費用作為代價的。底層的套接字可以用來開發客戶/服務器系統,但是由于大多數Java I/O類和對象不太容易匹配,如何通過套接字傳遞完成的對象呢?對象序列化是一個允許您以比特流方式讀/寫完成對象的機制。
將底層的套接字和對象序列化結合在一起,您將得到一個強大的、高效的、可替代RMI的機制,通過套接字來傳遞對象還能克服使用RMI的高費用的問題。
對象序列化概述
對象序列化機制對于需要將對象的狀態保存到文件中,而后能夠通過讀入對象狀態來重新構造對象,恢復程序狀態,或者使用套接字在網絡上傳送對象的程序來說,是很有用的。通過讓類實現java.io.Serializable 接口可以將類序列化。這個接口是一個制造者(marker)接口。也就是說,對于要實現它的類來說,該接口不需要實現任何方法。它主要用來通知Java虛擬機(JVM),需要將一個對象序列化。
將對象讀出或者寫入流的主要類有兩個: ObjectOutputStream與ObjectInputStream 。ObjectOutputStream 提供用來將對象寫入輸出流的writeObject方法, ObjectInputStream提供從輸入流中讀出對象的readObject方法。注意使用這些方法的對象必須被序列化,這非常重要。也就是說,這些類必須實現Serializable接口。
序列化已經存在的類
了解了對象序列化的基礎知識之后,我們來看看如何對流讀/寫對象或現有的已序列化類實例。要將一個對象寫入輸出流,先建立一個輸出流,然后使用writeObject對象保存到文件中。
注意: Date類是可序列化的。換句話說,它實現 Serializable接口。
例程 1: SaveDate.java
import java.io.*; public class SaveDate { public static void main(String argv[]) throws Exception { |
讀入對象,然后重新構造它的狀態都很容易。例程2中的代碼向您展示了如何讀一個已經序列化的對象并且打印它的信息。
例程 2: ReadDate.java
import java.io.*; public class ReadDate { public static void main(String argv[]) throws Exception { |
在上面的例子中我們使用了Date類的一個實例,這是一個現成的已序列化的Java類。也許您會問這樣的問題:是不是所有現成的Java類都是可序列化的?答案是否定的。這不僅因為這樣做沒必要,而且將某些類序列化是毫無意義的。使用JDK中的serialver工具,可以判斷一個類是不是可序列化的。您可以在命令行模式下使用如下命令:
c:> serialver java.util.Date java.util.Date: static final long serialVersionUID = 7523967970034938905L; |
(這個例子測試Date類是不是可序列化。輸出結果表示Date類是可序列化的,并且打印出了這個類的版本唯一標識符。)
或者,您也可以使用如下命令啟動圖形界面下的serialver工具:
c:> serialver -show
這個命令將彈出一個如圖1所示的窗口,在這個窗口中寫入您想檢查的類的名字(包括路徑)。圖1顯示的結果表示 Date類是可序列化的。
圖 1: Date是個可序列化的類
再說一次,不是所有的Java類都是可序列化的。舉個例子,圖2表明Socket類是不可序列化的。
圖2: Socket是個不可序列化的類