JAVA 序列化 和 反序列化 (Externalizable Serializable) 那些事
阿新 • • 發佈:2019-01-31
序列化控制
-
當我們對序列化進行控制時,可能某個特定子物件不想讓Java序列化機制自動儲存與恢復。如果子物件表示的是我們不希望將其序列化的敏感資訊(如密碼),通常會面臨這種情況。即使物件中的這些資訊是private屬性,一經序列化處理,人們就可以通過讀取檔案或者攔截網路傳輸的方式來訪問到它。有兩種辦法可以防止物件的敏感部分被序列化:
- 實現
Externalizable
代替實現Serializable
介面來對序列化過程進行控制,Externalizable
繼承了Serializable
介面,同時增添了兩個方法:writeExternal()
和readExternal()
。
兩者在反序列化時的區別:
- 對Serializable物件反序列化時,
- 對Externalizable物件反序列化時,會先呼叫類的不帶引數的構造方法,這是有別於預設反序列方式的。如果把類的不帶引數的構造方法刪除,或者把該構造方法的訪問許可權設定為private、預設或protected級別,會丟擲java.io.InvalidException: no valid constructor
-Externalizable
的替代方法:如果不是特別堅持實現Externalizable介面,那麼還有另一種方法。我們可以實現Serializable
介面,並新增writeObject()
和readObject()
的方法。一旦物件被序列化或者重新裝配,就會分別呼叫那兩個方法。也就是說,只要提供了這兩個方法,就會優先使用它們,而不考慮預設的序列化機制。這些方法必須含有下列準確的簽名:
private void writeObject(ObjectOutputStream stream) throws
- 可以用transient
關鍵字逐個欄位地關閉序列化,它的意思是“不用麻煩你儲存或恢復資料—我自己會處理的”。由於Externalizable物件在預設情況下不儲存它們的任何欄位,所以transient關鍵字只能和Serializable物件一起使用。 - 實現