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的方法區中讀取的。