Java中序列化與反序列化
在程式執行的過程中,所有的物件都是儲存在記憶體中的,這意味著當程式執行結束的時候,作業系統會把分配給物件的記憶體全部回收。
那有什麼辦法可以把物件儲存起來?
序列化就可以幫我們做到,序列化是將物件的狀態資訊轉換成可取的格式的過程,可以儲存為檔案,或者透過網路傳送資料時進行編碼的過程,可以是位元組或是XML等格式。其相反的過程就被稱為反序列化。
Java中準備了 Serializable
、 Externalizable
兩個介面(需要序列化的類必須實現這兩個介面其一),和 ObjectOutputStream
、 ObjectInputStream
兩個類來幫助開發者實現序列化與反序列化。
Serializable Code
只需在需要序列化的類上實現 Serializable
介面,即可通過 ObjectOutputStream
實現序列化到檔案系統中。

輸出結果為 Person{name='MrXieXie', age=null, password='null'}
注意:序列化到檔案後,將 password
的值重置為 null
。
可以看出在 Serializable
,靜態變數還有被 transient
標註的變數不會被序列化。
那麼是不是所有的靜態變數和被 transient
標註的變數就不會被序列化呢?讓我們來看一下 Externalizable
介面。
Externalizable Code
使用 Externalizable
實現序列化要比 Serializable
複雜一丟丟,需要實現 writeExternal
和 readExternal
方法,這兩個方法會在序列化和反序列化時呼叫。
需要注意的是,該介面需要呼叫被序列化類的無參構造器,若不提供則會丟擲異常 java.io.InvalidClassException: cn.mrxiexie.serializable.Car; no valid constructor

輸出結果為 Car{name='MrXieXie', brand='MrXieXie', price=1234567.89}
注意:序列化到檔案後,將 price
的值重置為 null
。
可以看出即使是靜態變數和被 transient
標註的變數還是會被序列化。原因很簡單, Serializable
介面是自動序列化,當發現有 transient
標註的變數時則不序列化該變數,而 Externalizable
介面則是需要在 writeExternal
方法中指定需要序列化的變數。