天天看點

Java入門 - 進階教程 - 04.序列化序列化

原文位址: http://www.work100.net/training/java-serialization.html 更多教程: 光束雲 - 免費課程

序列化

序号 文内章節 視訊
1 概述 -
2 序列化對象
3 反序列化對象

請參照如上

章節導航

進行閱讀

1.概述

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

2.序列化對象

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();
      }
   }
}           

3.反序列化對象

下面的

DeserializeDemo

程式執行個體了反序列化,

/tmp/employee.ser

存儲了

Employee

對象。

import java.io.*;
 
public class DeserializeDemo
{
   public static void main(String [] args)
   {
      Employee e = null;
      try
      {
         FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
         ObjectInputStream in = new ObjectInputStream(fileIn);
         e = (Employee) in.readObject();
         in.close();
         fileIn.close();
      }catch(IOException i)
      {
         i.printStackTrace();
         return;
      }catch(ClassNotFoundException c)
      {
         System.out.println("Employee class not found");
         c.printStackTrace();
         return;
      }
      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

屬性為

上一篇:

泛型

下一篇:

網絡程式設計
如果對課程内容感興趣,可以掃碼關注我們的

公衆号

QQ群

,及時關注我們的課程更新
Java入門 - 進階教程 - 04.序列化序列化
Java入門 - 進階教程 - 04.序列化序列化