java中的序列化與transient關鍵字

    序列化和transient關鍵字應該屬於java中較高級的話題,筆者(ymh)今天花一點時間小結一些這部分知識,希望能給初學者一些幫助。若有錯誤希望指出,學無止境。轉載請註明出處!

什麼是序列化?

      序列化 (Serialization)將對象的狀態信息轉換爲可以存儲或傳輸的形式的過程。在序列化期間,對象將其當前狀態寫入到臨時或持久性存儲區。以後,可以通過從存儲區中讀取或反序列化對象的狀態,重新創建該對象。

如何實現序列化?

    java中要想一個類的實例能夠被序列化,則該類可以實現Serializable接口,這是一個空接口,其中並沒有任何需要實現的方法,僅用來在編譯時讓編譯器標識該類的實例可被序列化,實現Serializable接口的類的實例屬性將自動參與序列化過程。

   另外,java類也可以實現Externalizable接口,該接口是Serializable接口的子接口,有兩個抽象方法:

實現Externalizable接口的java類需要writeExternal方法中明確指定哪些屬性要參與序列化過程。

transient關鍵字的用途?

     transient關鍵字只能用於修飾變量,不能修飾方法和類。若一個類中有些屬性需要被序列化,應先實現Serializable接口,而有一些屬性包含敏感信息,如密碼、銀行卡號等,這些信息若不想被序列化,可以用transient關鍵字修飾。被transient修飾的屬性將不參與序列化過程。

 

Serializable接口配合transient關鍵字使用案例:

public class SerializationDemo {
 
   final static class Person implements Serializable{
    private transient String id;  //transient修飾的實例屬性
    private String name;
    private static int count;
    private static transient String desc; //transient修飾的類屬性
    public Person(){}
    public Person(String id,String name,int count1,String desc1)
    {
     this.id=id;
     this.name=name;
     count=count1;
     desc=desc1;
    }
   }
  
 public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
  System.out.println(“序列化:將對象寫入文件”);
 Person person=new Person(UUID.randomUUID().toString(), “張三”, 11, “我是張三”);
 System.out.println(“transient修飾的實例屬性:”+person.id);
 System.out.println(“普通實例屬性:”+person.name);
 System.out.println(“普通類屬性:”+person.count);
 System.out.println(“transient修飾的類屬性:”+person.desc);
 //序列化
 File objectFile=new File(“f:/mm.txt”);
 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(objectFile));
 oos.writeObject(person);
 oos.close();
 person=null;
 //反序列化
 System.out.println(“反序列化:從文件中讀取對象”);
 Person.count=22;
 ObjectInputStream ois=new ObjectInputStream(new FileInputStream(objectFile));
 person=(Person) ois.readObject();
 System.out.println(“transient修飾的實例屬性:”+person.id);
 System.out.println(“普通實例屬性:”+person.name);
 System.out.println(“普通類屬性:”+person.count);
 System.out.println(“transient修飾的類屬性:”+person.desc);
 ois.close();
}
  
}

輸出結果:

結論:

1、對於實例屬性來說,被transient修飾的實例屬性將不會參與序列化。

2、對於類屬性來說,無論類屬性是否被transient關鍵字修飾,類屬性都不會參加序列化過程。

可以這樣理解:序列化是針對對象的操作過程,而類屬性是屬於類的一部分,不屬於某個具體的實例,因此類屬性不參與序列化。

上面測試代碼也很好的佐證了這一觀點,因爲若類屬性能夠被序列化,則反序列化讀取到的類屬性值應該與序列化時寫入的類屬性值一致,但代碼中反序列化前修改了類屬性值,反序列化讀取到的該類屬性值跟着變化,說明該類屬性的值並不是從反序列化的過程中讀取到的,實際上是從JVM的方法區中讀取的。

 

 

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