transient修飾符


1.簡述

  transient修飾符用於類屬性、變量,表示該類的序列化過程在為該類的任何實例創建持久字節流時應該忽略此類變量。

  transient使用場景

  • 在類實現序列化接口,而類下某個變量不想被序列化的情況下,用transient修飾該變量,可避免該變量被序列化。

2.transient的使用

  在Java中,對象的序列化可以通過兩種接口來實現,若實現的是Serializable接口,則所有的序列化將會自動進行,若實現的是Externalizable接口,則沒有任何東西可以自動序列化,需要在writeExternal方法中進行手動指定所要序列化的變量,這與是否被transient修飾無關。

  實現Serializable接口示例

public class Test {
    public static void main(String[] args) throws Exception {
        User user = new User("test", "123456");
        System.out.println("寫入文件前:name="+user.getName()+" password="+user.getPassword());
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("d:/Desktop/user.txt"));
        out.writeObject(user);
        out.flush();
        out.close();
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("d:/Desktop/user.txt"));
        User u = (User)in.readObject();
        in.close();
        System.out.println("重新讀取后:name="+u.getName()+" password="+u.getPassword());
    }
}

class User implements Serializable{
    private static final long serialVersionUID = 1L;
    private String name;
    private transient String password;
    
    public User(String name,String password){
        this.name = name;
        this.password = password;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}
View Code

運行結果

寫入文件前:name=test password=123456

重新讀取后:name=test password=null

  通過上面的示例我們可以看出以下幾點:

  • 一旦變量被transient修飾,變量將不再是對象持久化的一部分,該變量內容在序列化后無法獲得訪問。
  • transient關鍵字只能修飾變量,而不能修飾方法和類。注意,本地變量是不能被transient關鍵字修飾的。變量如果是用戶自定義類變量,則該類需要實現Serializable接口。
  • 被transient關鍵字修飾的變量不再能被序列化,一個靜態變量不管是否被transient修飾,均不能被序列化。

  實現Externalizable接口示例

public class Test {
    public static void main(String[] args) throws Exception {
        User user = new User("test", "123456");
        System.out.println("寫入文件前:name="+user.getName()+" password="+user.getPassword());
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("d:/Desktop/user.txt"));
        out.writeObject(user);
        out.flush();
        out.close();
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("d:/Desktop/user.txt"));
        User u = (User)in.readObject();
        in.close();
        System.out.println("重新讀取后:name="+u.getName()+" password="+u.getPassword());
    }
}

class User implements Externalizable{
    private String name;
    private String password;
    
    public User(){}
    public User(String name,String password){
        this.name = name;
        this.password = password;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
        name = (String)in.readObject();
    }
}
View Code

運行結果

寫入文件前:name=test password=123456

重新讀取后:name=test password=null

  通過上面的示例我們可以看出,在Exteralizable接口實現類中完全不一樣,被transient修飾的屬性,在exteralWrite中被寫入,就能被序列化。

3.總結

transient使用總結

  • 修飾符transient可以應用於類的字段成員,以關閉這些字段成員的序列化。
  • 你可以在需要對現有狀態字段進行保護或計算的字段的類中使用transient修飾符。當序列化那些字段(如日志記錄器和線程)毫無意義時,可以使用它。
  • 序列化不關心訪問修飾符,如private。所有非transient字段都被認為是對象持久狀態的一部分,並且都符合持久狀態的條件(實現Serializable接口的情況下)。
  • 無論何時將任何final字段、引用計算為常量表達式,JVM都會對其進行序列化,忽略transient修飾符的存在。
  • HashMap類是java中transient修飾符的一個很好的用例。


免責聲明!

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



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