關鍵字transient是幹啥的
百度百科的解釋:
Java語言的關鍵字,變數修飾符,如果用transient宣告一個例項變數,當物件儲存時,它的值不需要維持。換句話來說就是,用transient關鍵字標記的成員變數不參與序列化過程。
作用: Java的serialization提供了一種持久化物件例項的機制。當持久化物件時,可能有一個特殊的物件資料成員,我們不想用serialization機制來儲存它。為了在一個特定物件的一個域上關閉serialization,可以在這個域前加上關鍵字transient。當一個物件被序列化的時候,transient型變數的值不包括在序列化的表示中,然而非transient
編碼試驗加以證明:
1.自定義類(為了方便,我直接在main方法所在類中新增的一個靜態)
public static class TransientTest implements Serializable{ private static final long serialVersionUID = 233858934995755239L; private String name1; private transient String name2; public TransientTest(String name1,String name2){ this.name1 = name1; this.name2 = name2; } public String toString(){ return String.format("TransientTest.toString(): name1=%s,name2=%s", name1,name2); } }
2.寫一個測試方法
public static void testTransient(){ String name1="常規屬性",name2="transient修飾的屬性"; TransientTest test = new TransientTest(name1, name2); System.out.println("序列化前:"+test.toString()); ObjectOutputStream outStream; ObjectInputStream inStream; String filePath = "D:/test/object/TransientTest.obj"; try { outStream = new ObjectOutputStream(new FileOutputStream(filePath)); outStream.writeObject(test); inStream = new ObjectInputStream(new FileInputStream(filePath)); TransientTest readObject = (TransientTest)inStream.readObject(); System.out.println("序列化後:"+readObject.toString()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
3.在main方法中執行,然後可以看到得到的結果為
印證了上面所講的“用transient關鍵字標記的成員變數不參與序列化過程”。
用二進位制檢視器開啟這個檔案也可以看到,資料中只有name1,沒有name2。(請忽略亂碼問題,這個不是重點哈。)
延伸:
在檢視JDK原始碼的時候會發現很多地方都會加上transient關鍵字來修飾一些屬性,那究竟是出於什麼考慮才這麼做呢?
我覺得,應該是為了節約磁碟空間,避免造成不必要的浪費吧。
以ArrayList中的 transient Object[] elementData 為例,這個成員變數的註釋為:
翻譯出來就是:
/ * *
*儲存ArrayList元素的陣列緩衝區。
* ArrayList的容量是這個陣列緩衝區的長度。任何
*帶有elementData的空ArrayList == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
*當新增第一個元素時,將被擴充套件到DEFAULT_CAPACITY。
* /
也就是說,這個緩衝區在序列化時就不需要再寫入磁碟,因為它是“不必要”的。
個人觀點,僅供參考,如有不足之處,歡迎批評指正!