1.序列化是幹什麼的?
簡單說就是為了儲存在記憶體中的各種對象的狀态,
也就是執行個體變量,不是方法,
并且可以把儲存的對象狀态再讀出來。
雖然你可以用你自己的各種各樣的方法來儲存object states,
但是java給你提供一種應該比你自己好的儲存對象狀态的機制,那就是序列化。
2.什麼情況下需要序列化
當你想把的記憶體中的對象狀态儲存到一個檔案中或者資料庫中時候;
當你想用套接字在網絡上傳送對象的時候;
當你想通過rmi傳輸對象的時候;
3.一個例子
序列化需要實作serializable或者externalizable 接口
下面的是實作serializable接口,最後會提到externalizable
java的序列化和反序列化
如果你想學習java可以來這個群,首先是二二零,中間是一四二,最後是九零六,裡面有大量的學習資料可以下載下傳。
4.使用transient
在一些特殊場景下,比如銀行賬戶對象,出于保密考慮,
不希望對存款金額進行序列化。或者類的一些引用類型的成員是不可序列化的。
此時可以使用transient關鍵字修飾不想被或者不能被序列化的成員變量。
需要注意的是transient隻能修飾屬性(filed),不能修飾類或方法。
一個靜态變量不管是否被transient修飾,均不能被序列化。
5.自定義序列化
transient提供了一種簡潔的方式将被transient修飾的成員屬性完全隔離在序列化機制之外。
這樣子固然不錯,但是java還提供了一種自定義序列化機制讓開發者更自由地控制如何序列化各個成員屬性,
或者不序列化某些屬性(與transient效果相同)。
5.1 writeobject和readobject
這兩個方法和objectoutputstream及objectinputstream裡對應的方法名稱相同。
實際上,盡管這兩個方法是private型的,但是仍然是在被序列化(或反序列化)階段被外部類objectoutputstream(或objectinputstream)調用。
僅以序列化為例:
objectoutputstream在執行自己的writeobject方法前會先通過反射在要被序列化的對象的類中
查找有無自定義的writeobject方法,
如有的話,則會優先調用自定義的writeobject方法。
因為查找反射方法時使用的是getprivatemethod,
是以自定以的writeobject方法的作用域要被設定為private。
通過自定義writeobject和readobject方法可以完全控制對象的序列化與反序列化。
5.2 writereplace和readresolve
writereplace和readresolve是一種更徹底的序列化的機制,
它甚至可以将序列化的目标對象替換為其它的對象。
但是與writeobject和readobject不同的是,
這二者不是必須要一起使用的,而且盡量應分開使用。
若一起使用的話,隻有writereplace會生效。
6.使用externalizable
一開始有提到過實作externalizable接口也可以實作類的序列化。
使用這種方法,可以由開發者完全決定如何序列化和反序列化目标對象。
externalizable接口提供了writeexternal和readexternal兩個方法。
實際上這種方法和前面的自定義序列化方法很相似,
隻是externalizable強制自定義序列化。
在使用了externalizable的類中仍可以使用writereplace和readresolve方法。
使用externalizable進行序列化較之使用serializable性能略好,但是複雜度較高。