Java序列化技術

在實際開發中,我們會將一個對象寫入到一個文件中,進行持久化. 那麼這個類必須要實現一個Serializable接口,才能寫入!那麼java是怎麼進行持久化保存對象呢?

Java序列化就是將一個對象轉化成一串二進制表示的字節數組,通過保存或轉移這些字節數據來達到持久化的目的。需要持久化,對象必須繼承java.io.Serializable接口。反序列化則是相反的過程,將這個字節數據再重新構造成對象。我們知道反序列化時,必須有原始類作爲模板,才能將這個對象還原,從這個過程我們可以猜測,序列化的數據並不像class文件那樣保存類的完整的結構信息。

那麼序列化的數據到底都含有哪些信息,如下面的代碼所示:

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Student implements Serializable {
    private static final long serialVersionUID = 1396269444885402064L;
    public int num = 3190; 

    public static void main(String[] args) {
        try {
            FileOutputStream fos = new FileOutputStream("student.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            Student s = new Student();
            oos.writeObject(s);
            oos.flush();
            oos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

序列化的文件二進制字節數據如下:

Java序列化技術

解析:

ac ed: STREAM_MAGIC 聲明使用了序列化協議。

 00 05: STREAM_VERSION 序列化協議版本。

 73: TC_OBJECT 聲明這是一個新的對象。

 72: TC_CLASSDESC聲明這裏開始一個新class。

 72 00 07 53 74 75 64 65 6E 74: Student的完整類名。  

 13 60 8B A9 91 20 51 D0: serialVersionUID,序列化ID,如果沒有 指定,則會由算法隨機生成一個8字節的ID。

 02: 標記號,該值聲明該對象支持序列化。

 00 01: 該類所包含的域的個數爲1。

 49:域屬性,49代表“I”,也就是Int類型。

 00 03:域名字的長度,爲3。

 6e 75 6d: num屬性的名稱。

 78:TC_ENDBLOCKDATA,對象塊結束的標誌。

 70:TC_NULL,說明沒有其他超類的標誌.

 00 00 05 6e:3190的數值。

雖然Java的序列化能夠保證對象狀態的持久保存,但是遇到一些對象結構複雜的情況還是比較難處理的,下面是對一些複雜的對象情況的總結:

1.當父類繼承Serializable接口時,所有子類都可以被序列化。

2.子類實現了Serializable接口,父類沒有,父類的屬性不能序列化(不報錯,數據會丟失),但是在子類中的屬性仍能正確序列化。

3.如果序列化的屬性是對象,則這個對象也必須實現Serializable接口,否則會報錯。

4.在反序列化時,如果對象的屬性有修改或刪除,則修改的部分屬性會丟失,但不會報錯。

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