java.io.serializable 2

java.io.serializable - [技術探討]

版權聲明:轉載時請以超鏈接形式標明文章原始出處和作者信息及本聲明
http://lvdairy.blogbus.com/logs/25344996.html

 

對象序列化概述
對象序列化機制對於需要將對象的狀態保存到文件中,而後能夠通過讀入對象狀態來重新構造對象,恢復程序狀態,或者使用套接字在網絡上傳送對象的程序來說,是很有用的。通過讓類實現java.io.Serializable 接口可以將類序列化。這個接口是一個製造者(marker)接口。也就是說,對於要實現它的類來說,該接口不需要實現任何方法。它主要用來通知Java虛擬機(JVM),需要將一個對象序列化。

將對象讀出或者寫入流的主要類有兩個: ObjectOutputStream與ObjectInputStream 。ObjectOutputStream 提供用來將對象寫入輸出流的writeObject方法, ObjectInputStream提供從輸入流中讀出對象的readObject方法。注意使用這些方法的對象必須被序列化,這非常重要。也就是說,這些類必須實現Serializable接口。

序列化已經存在的類
瞭解了對象序列化的基礎知識之後,我們來看看如何對流讀/寫對象或現有的已序列化類實例。要將一個對象寫入輸出流,先建立一個輸出流,然後使用writeObject對象保存到文件中。


--------------------------------------------------------------------------------
注意: Date類是可序列化的。換句話說,它實現 Serializable接口。
--------------------------------------------------------------------------------

例程 1: SaveDate.java

import java.io.*;
import java.util.Date;

public class SaveDate {

  public static void main(String argv[]) throws Exception {
    FileOutputStream fos = new FileOutputStream("date.out");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    Date date = new Date();
    oos.writeObject(date);
    oos.flush();
    oos.close();
    fos.close();
  }
}

讀入對象,然後重新構造它的狀態都很容易。例程2中的代碼向您展示瞭如何讀一個已經序列化的對象並且打印它的信息。


例程 2: ReadDate.java

import java.io.*;
import java.util.Date;

public class ReadDate {

  public static void main(String argv[]) throws Exception {
    FileInputStream fis = new FileInputStream("date.out");
    ObjectInputStream ois = new ObjectInputStream(fis);
    Date date = (Date) ois.readObject();
    System.out.println("The date is: "+date);
    ois.close();
    fis.close();
  }
}

在上面的例子中我們使用了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類是可序列化的。

 

再說一次,不是所有的Java類都是可序列化的。舉個例子,圖2表明Socket類是不可序列化的。


序列化用戶自己的類
現在,讓我們看看如何序列化用戶自己寫的類。在這個例子中,我們將建立一個用戶類UserInfo,見例程3。爲了讓它可序列化,UserInfo類實現了Serializable接口。

例程 3: UserInfo.java

import java.io.*;
import java.util.*;

public class UserInfo implements Serializable {
   String name = null;

   public UserInfo(String name) {
      this.name = name;
   }

   public void printInfo() {
      System.out.println("The name is: "+name);
   }
}

下一步就是建立一個能創建UserInfo類實例的類,然後將對象寫入輸出流中,如例程4。本例中的輸出流是一個名爲"name.out"的文件。要注意的是,例程4 中的writeObject方法可以被調用任意多次,將任意多個對象寫入輸出流。

例程 4: SaveInfo.java

import java.io.*;
import java.util.Date;

public class SaveInfo {

  public static void main(String argv[]) throws Exception {
    FileOutputStream fos = new FileOutputStream("name.out");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    // create two objects
    UserInfo user1 = new UserInfo("Java Duke");
    UserInfo user2 = new UserInfo("Java Blue");
    // write the objects to the output stream
    oos.writeObject(user1);
    oos.writeObject(user2);
    oos.flush();
    oos.close();
    fos.close();
  }
}

最後,我們寫一個將已經保存的對象讀入的類,並且調用一個如例程5所示的方法。和writeObject 一樣,readObject方法能被調用任意多次,從輸入流中讀入任意多個對象。

例程 5: ReadInfo.java

import java.io.*;
import java.util.Date;

public class ReadInfo {

  public static void main(String argv[]) throws Exception {
    FileInputStream fis = new FileInputStream("name.out");
    ObjectInputStream ois = new ObjectInputStream(fis);
    // read the objects from the input stream (the file name.out)
    UserInfo user1 = (UserInfo) ois.readObject();
    UserInfo user2 = (UserInfo) ois.readObject();
    // invoke a method on the constructed object
    user1.printInfo();
    user2.printInfo();
    ois.close();
    fis.close();
  }
}

要測試這個例子,請編譯如下源文件:UserInfo.java, SaveInfo.java, 和 ReadInfo.java。運行 SaveInfo,然後運行ReadInfo,將看到類似下面的輸出結果:

The name is: Java Duke
The name is: Java Blue

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