源碼中transient的用途


  Java的serialization提供了一種持久化對象實例的機制。當持久化對象時,可能有一個特殊的對象數據成員,我們不想用serialization機制來保存它。為了在一個特定對象的一個域上關閉serialization,可以在這個域前加上關鍵字transient,transient是Java語言的關鍵字,用來表示一個域不是該對象串行化的一部分。當一個對象被串行化的時候,transient型變量的值不包括在串行化的表示中,然而非transient型的變量是被包括進去的。例如序列化對象的時候,有些屬性就不會序列化到指定的目的地中。像銀行卡、密碼等等這些數據。這個需要根據業務情況了。

  具體案例可參考:java 中的關鍵字 transient 這篇文章你再也不用愁了

那么,讓我們看一下序列化的代碼如下:

 1 public class LoggingInfo implements java.io.Serializable {   
 2     private Date loggingDate = new Date();   
 3     private String uid;   
 4     private transient String pwd;   
 5       
 6     LoggingInfo(String user, String password) {   
 7         uid = user;   
 8         pwd = password;   
 9     }   
10     public String toString() {   
11         String password=null;   
12         if(pwd == null) {   
13             password = "NOT SET";   
14         }   
15         else {   
16             password = pwd;   
17         }   
18         return "logon info: \n   " + "user: " + uid +   
19             "\n   logging date : " + loggingDate.toString() +   
20             "\n   password: " + password;
21     }
22 }

現在我們再創建一個這個類的實例,並且串行化(serialize)它 ,然后將這個串行化對象寫如磁盤。

 1 LoggingInfo logInfo = new LoggingInfo("MIKE", "MECHANICS");
 2 System.out.println(logInfo.toString());
 3 try {
 4    ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("logInfo.out"));
 5    o.writeObject(logInfo);
 6    o.close();
 7 }   
 8 catch(Exception e) {//deal with exception}
 9 To read the object back, we can write
10 try {
11    ObjectInputStream in =new ObjectInputStream(new FileInputStream("logInfo.out"));
12    LoggingInfo logInfo = (LoggingInfo)in.readObject();
13    System.out.println(logInfo.toString());
14 }
15 catch(Exception e) {//deal with exception}

  運行這段代碼,我們會注意到從磁盤中讀回(read——back (de-serializing))的對象打印password為"NOT SET",此時是我們定義pwd域為transient時,所期望的正確結果。

  如果將pwd域前修飾符transient去掉,再做一次發現password內容會打印出傳入的參數內容,即:MECHANICS,也符合我們所期望的結果。

 

那到底什么時候使用這個關鍵字呢?處於什么考量呢,自己認為大概有以下兩點可以做考慮:

1. HashMap中的table中存儲的值數量是小於數組的大小的(數組擴容的原因),這個在元素越來越多的情況下更為明顯。如果使用默認的序列化,那些沒有元素的位置也會被存儲,就會產生很多不必要的浪費。

2. 對於HashMap來說(以及底層實現是利用HashMap的HashSet),由於不同的虛擬機對於相同hashCode產生的Code值可能是不一樣的,如果你使用默認的序列化,那么反序列化后,元素的位置和之前的是保持一致的,可是由於hashCode的值不一樣了,那么定位函數indexOf()返回的元素下標就會不同,這樣不是我們所想要的結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM