標籤: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(); } }}
序列化的檔案二進位位元組資料如下:
解析:
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.在還原序列化時,如果對象的屬性有修改或刪除,則修改的部分屬性會丟失,但不會報錯。
Java序列化技術