小夥子,你真的搞懂 transient 關鍵字了嗎?

作者:Java技術棧
來源:https://www.jianshu.com/p/f77c2a05ea49

先解釋下什麼是序列化

我們的對象並不只是存在內存中,還需要傳輸網絡,或者保存起來下次再加載出來用,所以需要Java序列化技術。

Java序列化技術正是將對象轉變成一串由二進制字節組成的數組,可以通過將二進制數據保存到磁盤或者傳輸網絡,磁盤或者網絡接收者可以在對象的屬類的模板上來反序列化類的對象,達到對象持久化的目的。

什麼是 transient?

簡單來說就是,被 transient 修飾的變量不能被序列化。

具體來看下面的示例1

小夥子,你真的搞懂 transient 關鍵字了嗎?

小夥子,你真的搞懂 transient 關鍵字了嗎?

輸出結果:

序列化之前
username: Java技術棧
id: javastack
序列化之後
username: Java技術棧
id: null

示例1在 id 字段上加了 transient 關鍵字修飾,反序列化出來之後值為 null,說明了被 transient 修飾的變量不能被序列化。

靜態變量能被序列化嗎?

這個話題也是最近棧長的Java技術棧vip群裡面討論的,大家對這個知識點比較模糊,我就寫了這篇文章測試總結一下。

小夥子,你真的搞懂 transient 關鍵字了嗎?

那麼,到底靜態變量能被序列化嗎?廢話少說,先動手測試下吧!

示例2:

小夥子,你真的搞懂 transient 關鍵字了嗎?

小夥子,你真的搞懂 transient 關鍵字了嗎?

輸出結果:

序列化之前
username: Java技術棧1
id: javastack
序列化之後
username: Java技術棧2
id: null

示例2把 username 改為了 public static, 並在反序列化出來之前改變了靜態變量的值,結果可以看出序列化之後的值並非序列化進去時的值。

由以上結果分析可知,靜態變量不能被序列化,示例2讀取出來的是 username 在 JVM 內存中存儲的值。

transient 真不能被序列化嗎?

繼續來看示例3:

小夥子,你真的搞懂 transient 關鍵字了嗎?

小夥子,你真的搞懂 transient 關鍵字了嗎?

輸出結果:

null
javastack

示例3的 id 被 transient 修改了,為什麼還能序列化出來?那是因為 User3 實現了接口 Externalizable,而不是 Serializable。

在 Java 中有兩種實現序列化的方式,Serializable 和 Externalizable,可能大部分人只知道 Serializable 而不知道 Externalizable。

這兩種序列化方式的區別是:實現了 Serializable 接口是自動序列化的,實現 Externalizable 則需要手動序列化,通過 writeExternal 和 readExternal 方法手動進行,這也是為什麼上面的 username 為 null 的原因了。

transient 關鍵字總結

1)transient修飾的變量不能被序列化;

2)transient只作用於實現 Serializable 接口;

3)transient只能用來修飾普通成員變量字段;

4)不管有沒有 transient 修飾,靜態變量都不能被序列化;


分享到:


相關文章: