Java的序列化和反序列化
1.序列化是幹什麼的?
簡單說就是為了保存在內存中的各種對象的狀態,
也就是實例變量,不是方法,
並且可以把保存的對象狀態再讀出來。
雖然你可以用你自己的各種各樣的方法來保存object states,
但是Java給你提供一種應該比你自己好的保存對象狀態的機製,那就是序列化。
2.什麼情況下需要序列化
當你想把的內存中的對象狀態保存到一個文件中或者數據庫中時候;
當你想用套接字在網絡上傳送對象的時候;
當你想通過RMI傳輸對象的時候;
3.一個例子
序列化需要實現Serializable或者Externalizable 接口
下麵的是實現Serializable接口,最後會提到Externalizable
Java的序列化和反序列化
Java的序列化和反序列化
Java的序列化和反序列化
如果你想學習java可以來這個群,首先是二二零,中間是一四二,最後是九零六,裏麵有大量的學習資料可以下載。
4.使用transient
在一些特殊場景下,比如銀行賬戶對象,出於保密考慮,
不希望對存款金額進行序列化。或者類的一些引用類型的成員是不可序列化的。
此時可以使用transient關鍵字修飾不想被或者不能被序列化的成員變量。
需要注意的是transient隻能修飾屬性(filed),不能修飾類或方法。
一個靜態變量不管是否被transient修飾,均不能被序列化。
5.自定義序列化
transient提供了一種簡潔的方式將被transient修飾的成員屬性完全隔離在序列化機製之外。
這樣子固然不錯,但是Java還提供了一種自定義序列化機製讓開發者更自由地控製如何序列化各個成員屬性,
或者不序列化某些屬性(與transient效果相同)。
5.1 writeObject和readObject
Java的序列化和反序列化
這兩個方法和ObjectOutputStream及ObjectInputStream裏對應的方法名稱相同。
實際上,盡管這兩個方法是private型的,但是仍然是在被序列化(或反序列化)階段被外部類ObjectOutputStream(或ObjectInputStream)調用。
僅以序列化為例:
ObjectOutputStream在執行自己的writeObject方法前會先通過反射在要被序列化的對象的類中
查找有無自定義的writeObject方法,
如有的話,則會優先調用自定義的writeObject方法。
因為查找反射方法時使用的是getPrivateMethod,
所以自定以的writeObject方法的作用域要被設置為private。
通過自定義writeObject和readObject方法可以完全控製對象的序列化與反序列化。
Java的序列化和反序列化
Java的序列化和反序列化
Java的序列化和反序列化
5.2 writeReplace和readResolve
writeReplace和readResolve是一種更徹底的序列化的機製,
它甚至可以將序列化的目標對象替換為其它的對象。
但是與writeObject和readObject不同的是,
這二者不是必須要一起使用的,而且盡量應分開使用。
若一起使用的話,隻有writeReplace會生效。
6.使用Externalizable
一開始有提到過實現Externalizable接口也可以實現類的序列化。
使用這種方法,可以由開發者完全決定如何序列化和反序列化目標對象。
Externalizable接口提供了writeExternal和readExternal兩個方法。
實際上這種方法和前麵的自定義序列化方法很相似,
隻是Externalizable強製自定義序列化。
在使用了Externalizable的類中仍可以使用writeReplace和readResolve方法。
使用Externalizable進行序列化較之使用Serializable性能略好,但是複雜度較高。
最後更新:2017-04-24 21:32:59