天天看點

Java序列化

 (1)序列化和反序列化其實就是對象和位元組之間的轉換。io之間進行資料傳輸,無論是網絡io,還是檔案io,都是以位元組為機關。而對象要想傳輸就必須首先轉化為位元組序列進行傳輸,接收端從位元組序列中反序列化得到對象。常見的應用就是網絡程式設計中傳輸對象,檔案系統中直接将對象資訊儲存在檔案中,還有就是頂頂大名的rmi技術,其實就是調用遠端對象的方法,這就涉及到對象的傳輸,其核心思想就是基于序列化機制。

(2)序列化機制的輸入方法為objectinputstream的readobject()方法,輸出為objectoutputstream的writeobject()方法。可以實作自己的readobject和writeobject方法,但必須是private,不是覆寫serializable的方法,而是序列化過程進行時會預設檢查實作serializable接口的類是否定義上述兩個方法,如果定義則調用這兩個方法進行序列化和反序列化,否則采用預設的處理方式,通過這種方式可以控制序列化過程,應用就是傳輸前可以将一些字段加密,然後接收後進行解密。其實還可以實作externalizable,但是感覺這種方式沒啥作用,通過自己實作readobject和wirteobject也可以完成同樣的功能。

(3)序列化id的作用是保證序列化和反序列化時是同一個類,可以采用預設的1l,也可以采用随機生成的方法。這個id除了保證反序列化成功外,更重要的用途是版本更新時,通過更改序列id,讓用戶端程式反序列化該對象時失敗,強制進行更新。

(4)序列化的過程就是将對象轉化為對應的位元組序列,這個轉化算法并不是簡單的将變量值記錄下來,還記錄了一些基本的類資訊。序列化時,首先根據序列化的對象其包含的對象,其繼承的父類,因為類的執行個體化首先是父類的執行個體化,然後才是其本身包括成員對象的執行個體化,是以通過解析這個對象圖,依次檢查是否實作serializable接口,進行序列化。父類可以不實作接口,子類從父類繼承的對象也就不參與執行個體化,成員對象必須實作serializable接口。通過将變量加上transient關鍵字,可以指定某些變量不參與執行個體化,也就是其值不記錄到位元組流中,包括成員變量,如果該成員變量不參與序列化,其也就沒必要實作serializable接口。序列化是将對象的資訊轉化為位元組,對于靜态變量這些屬于類的存儲單元,不進行序列化。

(5)序列化涉及到位元組序列的存儲優化,同樣的對象序列化後,除了第一個對象的位元組序列儲存,後續儲存的都是引用。是以無論相同的對象序列化多少次,反序列化得到的都是一個對象,當第一個對象序列化後,改變其值再序列化,改變後的值不會儲存,因為位元組序列已經儲存了,後面隻儲存引用。

繼續閱讀