做爲java中的一個關鍵字,tranisent用的並非不少,可是在某些關鍵場合,卻又起着極爲重要的做用,所以有必要對它進行一些必要的瞭解。java
1、定義:聲明不用序列化的成員域。(源自百度百科)app
2、做用:根據tranisent關鍵字的定義,咱們能夠很容易的概括出它的做用,那就是修飾變量,使之不能成爲對象持久化的一部分,固然,對於tranisent修飾的這個變量,也是有要求的,這個變量不能是本地變量,若是是用戶自定義的變量,那麼擁有這個變量的類必須實現Serializable接口;根據以前對static和final的描述,咱們知道它們除了能夠修飾變量以外,還能夠修飾方法和類,可是對於tranisent來講,它有且僅有能夠修飾變量的做用,對於方法和類,它是不容許修飾的。ide
1.修飾變量:對於tranisent修飾的變量,是不容許被序列化的。this
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class Rectangle implements Serializable { private static final long serialVersionUID = 1710022455003682613L; private Integer width; private Integer height; private transient Integer area; public Rectangle (Integer width, Integer height){ this.width = width; this.height = height; this.area = width * height; } public void setArea(){ this.area = this.width * this.height; } @Override public String toString(){ StringBuffer sb = new StringBuffer(40); sb.append("width : "); sb.append(this.width); sb.append("\nheight : "); sb.append(this.height); sb.append("\narea : "); sb.append(this.area); return sb.toString(); } } public class TransientExample { public static void main(String args[]) throws Exception { Rectangle rectangle = new Rectangle(3,4); System.out.println("1.原始對象\n"+rectangle); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("rectangle")); // 往流寫入對象 o.writeObject(rectangle); o.close(); // 從流讀取對象 ObjectInputStream in = new ObjectInputStream(new FileInputStream("rectangle")); Rectangle rectangle1 = (Rectangle)in.readObject(); System.out.println("2.反序列化後的對象\n"+rectangle1); rectangle1.setArea(); System.out.println("3.恢復成原始對象\n"+rectangle1); in.close(); } }
輸出結果:spa
1.原始對象 width : 3 height : 4 area : 12 2.反序列化後的對象 width : 3 height : 4 area : null 3.恢復成原始對象 width : 3 height : 4 area : 12
注:被transient關鍵字修飾的變量再也不能被序列化,一個靜態變量無論是否被transient修飾,均不能被序列化。code
那麼又會產生一個新的問題,是否被transient關鍵字修飾的變量真的就不能被序列化呢?對象
import java.io.Externalizable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; public class Person implements Externalizable { private transient String content = "是的,我會被序列化"; @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(content); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { content = (String) in.readObject(); } public static void main(String[] args) throws Exception { Person person = new Person(); ObjectOutput out = new ObjectOutputStream(new FileOutputStream( new File("test"))); out.writeObject(person); ObjectInput in = new ObjectInputStream(new FileInputStream(new File( "test"))); person = (Person) in.readObject(); System.out.println(person.content); out.close(); in.close(); } }
輸出結果:blog
是的,我會被序列化
十分意外的是,被transient關鍵字修飾的變量居然也能夠序列化了,這又是爲何呢?原來以前咱們所說的,全都是創建在該類是實現Serializable接口的,可是咱們知道,在java中,對象的序列化是能夠經過兩種接口來實現的,一個是Serializable接口,另外一個就是上圖中所展現的Externalizable接口,至於兩者的具體區別,這裏不詳細訴說了,可是實現Serializable接口,全部的序列化都是自動進行的,實現Externalizable接口則不一樣,須要咱們在writeExternal方法中進行手動序列化,所以這個時候transient就不可以起到什麼做用了,這也是爲何在上面的例子中變量content可以被序列化的緣由。接口
總結:雖然transient關鍵字不是那麼經常使用,可是卻不表明它不重要,這裏我就簡單的小結了一下,若是你們還有什麼好的建議,歡迎在評論區留言。get