天天看點

Java序列化

  java序列化

  java 提供了一種對象序列化的機制,該機制中,一個對象可以被表示為一個位元組序列,該位元組序列包括該對象的資料、有關對象的類型的資訊和存儲在對象中資料的類型。

  将序列化對象寫入檔案之後,可以從檔案中讀取出來,并且對它進行反序列化,也就是說,對象的類型資訊、對象的資料,還有對象中的資料類型可以用來在記憶體中建立對象。

  整個過程都是java虛拟機(jvm)獨立的,也就是說,在一個平台上序列化的對象可以在另一個完全不同的平台上反序列化該對象。

  類objectinputstream 和objectoutputstream是高層次的資料流,它們包含序列化和反序列化對象的方法。

  objectoutputstream 類包含很多寫方法來寫各種資料類型,但是一個特别的方法例外:

  public final void writeobject(object x) throws ioexception

  上面的方法序列化一個對象,并将它發送到輸出流。相似的objectinputstream 類包含如下反序列化一個對象的方法:

  public final object readobject() throws ioexception,

  classnotfoundexception

  該方法從流中取出下一個對象,并将對象反序列化。它的傳回值為object,是以,你需要将它轉換成合适的資料類型。

  為了示範序列化在java中是怎樣工作的,我将使用之前教程中提到的employee類,假設我們定義了如下的employee類,該類實作了serializable 接口。

  public class employee implements java.io.serializable

  {

  public string name;

  public string address;

  public transient int ssn;

  public int number;

  public void mailcheck()

  system.out.println("mailing a check to " + name

  + " " + address);

  }

  請注意,一個類的對象要想序列化成功,必須滿足兩個條件:

  該類必須實作 java.io.serializable 對象。

  該類的所有屬性必須是可序列化的。如果有一個屬性不是可序列化的,則該屬性必須注明是短暫的。

  如果你想知道一個java标準類是否是可序列化的,請檢視該類的文檔。檢驗一個類的執行個體是否能序列化十分簡答, 隻需要檢視該類有沒有實作java.io.serializable接口。

  序列化對象

  objectoutputstream 類用來序列化一個對象,如下的serializedemo例子執行個體化了一個employee對象,并将該對象序列化到一個檔案中。

  該程式執行後,就建立了一個名為employee.ser檔案。該程式沒有任何輸出,但是你可以通過代碼研讀來了解程式的作用。

  注意: 當序列化一個對象到檔案時, 按照java的标準約定是給檔案一個.ser擴充名。

  import java.io.*;

  public class serializedemo

  public static void main(string [] args)

  employee e = new employee();

  e.name = "reyan ali";

  e.address = "phokka kuan, ambehta peer";

  e.ssn = 11122333;

  e.number = 101;

  try

  fileoutputstream fileout =

  new fileoutputstream("/tmp/employee.ser");

  objectoutputstream out = new objectoutputstream(fileout);

  out.writeobject(e);

  out.close();

  fileout.close();

  system.out.printf("serialized data is saved in /tmp/employee.ser");

  }catch(ioexception i)

  i.printstacktrace();

  反序列化對象

  下面的deserializedemo程式反序列化在serializedemo程式中建立employee對象。

  public class deserializedemo

  employee e = null;

  fileinputstream filein = new fileinputstream("/tmp/employee.ser");

  objectinputstream in = new objectinputstream(filein);

  e = (employee) in.readobject();

  in.close();

  filein.close();

  return;

  }catch(classnotfoundexception c)

  system.out.println("employee class not found");

  c.printstacktrace();

  system.out.println("deserialized employee...");

  system.out.println("name: " + e.name);

  system.out.println("address: " + e.address);

  system.out.println("ssn: " + e.ssn);

  system.out.println("number: " + e.number);

  以上程式編譯運作結果如下所示:

  deserialized employee...

  name: reyan ali

  address:phokka kuan, ambehta peer

  ssn: 0

  number:101

  這裡要注意以下要點:

  readobject() 方法中的try/catch代碼塊嘗試捕獲 classnotfoundexception異常。對于jvm可以反序列化對象,它必須是能夠找到位元組碼的類。如果jvm在反序列化對象的過程中找不到該類,則抛出一個 classnotfoundexception異常。

  注意,readobject()方法的傳回值被轉化成employee引用。

  當對象被序列化時,屬性ssn的值為111222333,但是因為該屬性是短暫的,該值沒有被發送到輸出流。是以反序列化後employee對象的ssn屬性為0。(編輯:雷林鵬 )