線程安全---transient

轉自http://horst.sun.blog.163.com/blog/static/348849612007614494492/   
 
翻譯自http:
//www.devx.com/tips/Tip/13726   
 
Javaserialization提供了一種持久化對象實例的機制。當持久化對象時,可能有一個特殊的對象數據成員,我們不想   
serialization機制來保存它。爲了在一個特定對象的一個域上關閉serialization,可以在這個域前加上關鍵字transient   
transient
Java語言的關鍵字,用來表示一個域不是該對象串行化的一部分。當一個對象被串行化的時候,transient型變量的值不包括在串行化的表示中,然而非transient型的變量是被包括進去的。  
注意static變量也是可以串行化的 
 
首先,讓我們看一些Java serialization的代碼:   
public
 class LoggingInfo implements java.io.Serializable   
{   
    private Date loggingDate = new Date();   
    
private String uid;   
    
private transient String pwd;   
      
    LoggingInfo(String user, String password)   
    {   
        uid = user;   
        pwd = password;   
    }
   
    
public String toString()   
    {   
        String password=
null;   
        
if(pwd == null)   
        {   
        password = "NOT SET";   
        }
   
        
else  
        {   
            password = pwd;   
        }
   
        
return "logon info: \n   " + "user: " + uid +   
            "\n   logging date : " + loggingDate.toString() +   
            "\n   password: " + password;   
    }
   
}
   
  
現在我們創建一個這個類的實例,並且串行化(serialize) ,然後將這個串行化對象寫如磁盤。   
  
LoggingInfo logInfo 
new LoggingInfo("MIKE", "MECHANICS");   
System.out.println(logInfo.toString());   
try
  
{   
   ObjectOutputStream o = new ObjectOutputStream(   
                
new FileOutputStream("logInfo.out"));   
   o.writeObject(logInfo);   
   o.close();   
}
   
catch
(Exception e) {//deal with exception}   
  
To read the object back, we can write   
  
try  
{   
   ObjectInputStream in =
new ObjectInputStream(   
                
new FileInputStream("logInfo.out"));   
   LoggingInfo logInfo = (LoggingInfo)in.readObject();   
   System.out.println(logInfo.toString());   
}
   
catch(Exception e) {//deal with exception}   
  
如果我們運行這段代碼,我們會注意到從磁盤中讀回(read——back (de-serializing))的對象打印password"NOT SET"。這是當我們定義pwd域爲transient時,所期望的正確結果。   
現在,讓我們來看一下粗心對待transient域可能引起的潛在問題。假設我們修改了類定義,提供給transient域一個默認值,   
代碼如下:   
  
public class GuestLoggingInfo implements java.io.Serializable   
{   
    
private Date loggingDate = new Date();   
    
private String uid;   
    
private transient String pwd;   
      
    GuestLoggingInfo()   
    {   
        uid = "guest";   
        pwd = "guest";   
    }
   
    
public String toString()   
    {   
        
//same as above   
     }   
}
   
現在,如果我們穿行化GuestLoggingInfo的一個實例,將它寫入磁盤,並且再將它從磁盤中讀出,我們仍然看到讀回的對象打印password  "NOT SET"。當從磁盤中讀出某個類的實例時,實際上並不會執行這個類的構造函數,   
而是載入了一個該類對象的持久化狀態,並將這個狀態賦值給該類的另一個對象。  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章