Java基礎:序列化(Serializable)與還原序列化

來源:互聯網
上載者:User

標籤:

在學習IO中的ObjectOutputStream和ObjectInputStream時,會涉及到序列化和還原序列化的應用,那麼它們是什嗎?

一、概念

序列化:把對象轉換為位元組序列的過程,叫做對象的序列化。

還原序列化:把位元組序列恢複為對象的過程,叫做對象的還原序列化。

 

二、作用

主要有兩種用途:

1.把對象的位元組序列永久儲存在硬碟中,也就是把記憶體中的資料(對象)持久化處理。

2.可以在網路上傳輸對象的字元序列,對象不再局限於本地使用。

 

無論那種用途,實際上都是為了儲存在記憶體中的各種對象的狀態(也就是執行個體變數,不是方法),並且可以把儲存的對象狀態再讀出來。這是java提供的一種儲存對象狀態的機制。

 

三、應用

在開頭有提到,在java.io包中有兩個序列化對象的類,分別為:ObjectOutputStream將對象寫入位元組流,ObjectInputStream將位元組流重構為對象。

需要注意的是,被序列化的對象必須要實現Serializable或者Externalizable介面。

例子1:(為了方便閱讀,異常都做拋處理):

 1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.ObjectInputStream; 5 import java.io.ObjectOutputStream; 6 import java.io.Serializable; 7  8 public class Test { 9     public static void main(String[] args) throws Exception{10         Person p = new Person("zhangsan",20);11         serializePerson(p);12         Person p1 = deserializePerson();13         System.out.println(p1);        //結果列印zhangsan:20。14     }15 16 //    序列化17     private static void serializePerson(Object obj) throws Exception {18         ObjectOutputStream out= new ObjectOutputStream(new FileOutputStream(new File("c:\\obj.txt")));19         out.writeObject(obj);20         System.out.println("序列化成功");21         out.close();22     }23     24 //    還原序列化25     private static Person deserializePerson() throws Exception {26         ObjectInputStream in = new ObjectInputStream(new FileInputStream("c:\\obj.txt"));27         Person p1 = (Person)in.readObject();28         System.out.println("還原序列化成功");29         in.close();30         return p1;31     }32     33 }34 35 36 class Person implements Serializable {37 //    注意,如果不指定serialVersionUID,序列化時會按預設進行,也會產生serialVersionUID。38 //    但是如果後來有修改類中代碼,序列化產生的serialVersionUID也會改變,這時還原序列化就會失敗,發生異常。39     private static final long serialVersionUID = 1L;40     private String name;41     private int age;42     Person() {43         System.out.println("空參數建構函式");44     }45     public Person(String name, int age) {46         System.out.println("有參數建構函式");47         this.name = name;48         this.age = age;49     }50     51     public String toString() {52         return name+":"+age;53     }54 }

以上代碼運行結果為:

有參數建構函式
序列化成功
還原序列化成功
zhangsan:20

從結果可以看出,還原序列化時,並沒用通過Person類的建構函式,而是根據序列化的資料建立Person對象的。

要注意的是,預設serialVersionUID的取值是Java運行時,根據類的內部細節自動產生的。如果對類的原始碼作了修改,再重新編譯,新產生的類檔案的serialVersionUID的取值有可能也會發生變化。類的serialVersionUID的預設值完全依賴於Java編譯器的實現,對於同一個類,用不同的Java編譯器編譯,有可能會導致不同的 serialVersionUID,也有可能相同。為了提高serialVersionUID的獨立性和確定性,強烈建議在一個可序列化類別中顯示的定義serialVersionUID,為它賦予明確的值。

顯式定義serialVersionUID可以實現兩種目的:

1.若想不同版本的類(類有做過修改)序列化後,都能成功還原序列化(相容),就需要確保類的不同版本的類具有相同的serialVersionUID;

2.若不想不同版本的類序列化後還能成功還原序列化,就讓不同版本的類具有不同的serialVersionUID。

 

例子2:

先序列化:

 1 public class TestSerialze { 2     public static void main(String[] args) throws Exception{ 3         Person p = new Person("zhangsan",20); 4         serializePerson(p); 5     } 6  7 //    序列化 8     private static void serializePerson(Object obj) throws Exception { 9         ObjectOutputStream out= new ObjectOutputStream(new FileOutputStream(new File("c:\\obj.txt")));10         out.writeObject(obj);11         System.out.println("序列化成功");12         out.close();13     }14 }15 16 17 class Person implements Serializable {18 //    注意,如果不指定serialVersionUID,序列化時會按預設進行,也會產生serialVersionUID。19 //    但是如果修改類中內容後,序列化產生新的serialVersionUID,跟原來不一樣,這時還原序列化就會失敗,發生異常。20     private static final long serialVersionUID = 1L;21     private String name;22     private int age;23 //    靜態成員屬於類,不能被序列化。24     private static int count;25 //    瞬態也不能被序列化。26     transient private int key;27     28     Person() {29         System.out.println("空參數建構函式");30     }31     public Person(String name, int age) {32         System.out.println("有參數建構函式");33         this.name = name;34         this.age = age;35         count++;36         key++;37     }38     39     public String toString() {40         return name+":"+age+"..."+count+"..."+key;41     }42 }

後還原序列化:

import java.io.FileInputStream;import java.io.ObjectInputStream;public class TestDeserialze {    public static void main(String[] args) throws Exception{        Object obj = deserializeObject();        System.out.println(obj);    }    private static Object deserializeObject() throws Exception {        ObjectInputStream in = new ObjectInputStream(new FileInputStream("c:\\obj.txt"));        Object obj = in.readObject();        System.out.println("還原序列化成功");        in.close();        return obj;    }}

還原序列化得到的結果是:

還原序列化成功
zhangsan:20...0...0

以上可以看出被static和transient修飾的成員變數無法被序列化。

Java基礎:序列化(Serializable)與還原序列化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.