Java 對象的序列化(Serialization)淺談

來源:互聯網
上載者:User
一、序列化的概念和目的

1.什麼是序列化 

            對象的壽命通常隨著產生該對象的程式的終止而終止。有時候,可能需要將對象的狀態儲存下來,在需要時再將對象恢複。我們把對象的這種能記錄自己的狀態以便將來再生的能力。叫作對象的持久性(persistence)。對象通過寫出描述自己狀態的數值來記錄自己 ,這個過程叫對象的序列化(Serialization) 。序列化的主要任務是寫出對象執行個體變數的數值。如果交量是另一對象的引用,則引用的對象也要序列化。這個過程是遞迴的,序列化可能要涉及一個複雜樹結構的單行化,包括原有對象、對象的對象、對象的對象的對象等等。對象所有權的階層稱為圖表(graph)。

2.序列化的目的 

            Java對象的單行化的目標是為Java的運行環境提供一組特性,如下所示:

1)       盡量保持對象序列化的簡單扼要 ,但要提供一種途徑使其可根據開發人員的要求進行擴充或定製。

2)       序列化機制應嚴格遵守Java的物件模型 。對象的序列化狀態中應該存有所有的關於種類的安全特性的資訊。

3)       對象的序列化機制應支援Java的對象持久性。

4)       對象的序列化機制應有足夠的 可擴充能力以支援對象的遠程方法調用(RMI)。

5)       對象序列化應允許對象定義自身 的格式即其自身的資料流表示形式,可外部化介面來完成這項功能。

 

 二、序列化方法 
            從JDK1.1開始,Java語言提供了對象序列化機制 ,在java.io包中,介面Serialization用來作為實現對象序列化的工具 ,只有實現了Serialization的類的對象才可以被序列化。 

            Serializable介面中沒有任何的方法。當一個類聲明要實現Serializable介面時,只是表明該類參加序列化協議,而不需要實現任何特殊的方法。下面我們通過執行個體介紹如何對對象進行序列化。

1.定義一個可序列化對象 

            一個類,如果要使其對象可以被序列化,必須實現Serializable介面。我們定義一個類Student如下:

  1. import java.io.Serializable;   
  2.   
  3. public class Student implements Serializable {   
  4.   
  5.     int id;// 學號   
  6.   
  7.     String name;// 姓名   
  8.   
  9.     int age;// 年齡   
  10.   
  11.     String department; // 系別   
  12.   
  13.     public Student(int id, String name, int age, String department) {   
  14.   
  15.         this.id = id;   
  16.   
  17.         this.name = name;   
  18.   
  19.         this.age = age;   
  20.   
  21.         this.department = department;   
  22.   
  23.     }   
  24.   
  25. }  

2.構造對象的輸入/輸出資料流 

            要序列化一個對象,必須與一定的對象輸出/輸入資料流聯絡起來,通過對象輸出資料流將對象狀態儲存下來,再通過對象輸入資料流將對象狀態恢複。 

            java.io包中,提供了ObjectInputStream和ObjectOutputStream將資料流功能擴充至可讀寫對象 。在ObjectInputStream 中用readObject()方法可以直接讀取一個對象,ObjectOutputStream中用writeObject()方法可以直接將對象儲存到輸出資料流中。

  1. import java.io.FileInputStream;   
  2. import java.io.FileOutputStream;   
  3. import java.io.IOException;   
  4. import java.io.ObjectInputStream;   
  5. import java.io.ObjectOutputStream;   
  6.   
  7. public class ObjectSer {   
  8.   
  9.     public static void main(String args[]) throws IOException,   
  10.             ClassNotFoundException {   
  11.   
  12.         Student stu = new Student(981036, "LiuMing", 18, "CSD");   
  13.   
  14.         FileOutputStream fo = new FileOutputStream("data.ser");   
  15.   
  16.         ObjectOutputStream so = new ObjectOutputStream(fo);   
  17.   
  18.         try {   
  19.   
  20.             so.writeObject(stu);   
  21.   
  22.             so.close();   
  23.   
  24.         } catch (IOException e) {   
  25.             System.out.println(e);   
  26.         }   
  27.   
  28.         stu = null;   
  29.   
  30.         FileInputStream fi = new FileInputStream("data.ser");   
  31.   
  32.         ObjectInputStream si = new ObjectInputStream(fi);   
  33.   
  34.         try {   
  35.   
  36.             stu = (Student) si.readObject();   
  37.   
  38.             si.close();   
  39.   
  40.         } catch (IOException e)   
  41.   
  42.         {   
  43.             System.out.println(e);   
  44.         }   
  45.   
  46.         System.out.println("Student Info:");   
  47.   
  48.         System.out.println("ID:" + stu.id);   
  49.   
  50.         System.out.println("Name:" + stu.name);   
  51.   
  52.         System.out.println("Age:" + stu.age);   
  53.   
  54.         System.out.println("Dep:" + stu.department);   
  55.   
  56.     }   
  57.   
  58. }  

運行結果如下:

        Student Info:

  ID:981036

  Name:LiuMing

  Age:18

  Dep:CSD

 

 

            在這個例子中,我們首先定義了一個類Student,實現了Serializable介面 ,然後通過對象輸出資料流的writeObject()方法將Student對象儲存到檔案 data.ser中 。之後,通過對家輸入資料流的readObjcet()方法從檔案data.ser中讀出儲存下來的Student對象 。從運行結果可以看到,通過序列化機制,可以正確地儲存和恢複對象的狀態。

三、序列化的注意事項
        1.序列化能儲存的元素 

            序列化只能儲存對象的非靜態成員交量,不能儲存任何的成員方法和靜態成員變數,而且序列化儲存的只是變數的值,對於變數的任何修飾符都不能儲存。

        2.transient關鍵字 

            對於某些類型的對象,其狀態是瞬時的,這樣的對象是無法儲存其狀態的。例如一個Thread對象或一個FileInputStream對象 ,對於這些欄位,我們必須用transient關鍵字標明,否則編譯器將報措。 

            另外 ,序列化可能涉及將對象存放到 磁碟上或在網路上發達資料,這時候就會產生安全問題。因為資料位元於Java運行環境之外,不在Java安全機制的控制之中。對於這些需要保密的欄位,不應儲存在永久介質中 ,或者不應簡單地不加處理地儲存下來 ,為了保證安全性。應該在這些欄位前加上transient關鍵字。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.