java中transient關鍵字的做用

Java有個特色就是序列化,簡單地來講就是能夠將這個類存儲在物理空間(固然仍是以文件的形式存在),那麼當你從本地還原這個文件時,你能夠將它轉換爲它自己。這能夠極大地方便網絡上的一些操做,但同時,由於涉及到安全問題,因此並不但願把類裏面全部的東西都能存儲(由於那樣,別人能夠經過序列化知道類裏面的內容),那麼咱們就能夠用上transient這個關鍵字,它的意思是臨時的,即不會隨類一塊兒序列化到本地,因此當還原後,這個關鍵字定義的變量也就再也不存在。java

一般,咱們寫的程序都要求特定信息能持久存在或保存到磁盤上,以供一個程序使用或用在同一個程序的另外一次運行上.這種持久性能夠經過幾種方式來實現,包括寫到數據庫中或是利用JAVA爲對象序列化提供的支持.無論咱們選用什麼方法,類實例的持久性都是經過保存類的域的狀態來完成的,保存這些狀態,以便之後能夠對它們進行訪問或使用它們來建立相同的實例.然而,有可能並非全部的域都須要被保存起來.當一個實例被持久化時,其內部的一些域卻不須要持久化,則能夠用trainsient修飾符告訴編譯器指定的域不須要被持久保存.mysql

 Java的serialization提供了一種持久化對象實例的機制。當持久化對象時,可能有一個特殊的對象數據成員,咱們不想 用serialization機制來保存它。爲了在一個特定對象的一個域上關閉serialization,能夠在這個域前加上關鍵字transient。transient是Java語言的關鍵字,用來表示一個域不是該對象串行化的一部分。當一個對象被串行化的時候,transient型變量的值不包括在串行化的表示中,然而非transient型的變量是被包括進去的。sql

首先,讓咱們看一些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; 
    } 
}
serialization

如今咱們建立一個這個類的實例,而且串行化(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
}
serialize

若是咱們運行這段代碼,咱們會注意到從磁盤中讀回(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 
     } 
} 
transient

如今,若是咱們穿行化GuestLoggingInfo的一個實例,將它寫入磁盤,而且再將它從磁盤中讀出,咱們仍然看到讀回的對象打印password 爲 "NOT SET"。ide

當從磁盤中讀出某個類的實例時,實際上並不會執行這個類的構造函數,
而是載入了一個該類對象的持久化狀態,並將這個狀態賦值給該類的另外一個對象。函數

相關文章
相關標籤/搜索