在討論transient以前,有必要先搞清楚Java中序列化的含義;java
Java中對象的序列化指的是將對象轉換成以字節序列的形式來表示,這些字節序列包含了對象的數據和信息,一個序列化後的對象能夠被寫到數據庫或文件中,也可用於網絡傳輸,通常當咱們使用緩存cache(內存空間不夠有可能會本地存儲到硬盤)或遠程調用rpc(網絡傳輸)的時候,常常須要讓咱們的實體類實現Serializable接口,目的就是爲了讓其可序列化。數據庫
固然,序列化後的最終目的是爲了反序列化,恢復成原先的Java對象,要否則序列化後幹嗎呢,因此序列化後的字節序列都是能夠恢復成Java對象的,這個過程就是反序列化。緩存
Java中transient關鍵字的做用,簡單地說,就是讓某些被修飾的成員屬性變量不被序列化,這一看好像很好理解,就是不被序列化,那麼什麼狀況下,一個對象的某些字段不須要被序列化呢?若是有以下狀況,能夠考慮使用關鍵字transient修飾:網絡
一、類中的字段值能夠根據其它字段推導出來,如一個長方形類有三個屬性:長度、寬度、面積(示例而已,通常不會這樣設計),那麼在序列化的時候,面積這個屬性就不必被序列化了;app
二、其它,看具體業務需求吧,哪些字段不想被序列化;ide
PS,記得以前看HashMap源碼的時候,發現有個字段是用transient修飾的,我以爲仍是有道理的,確實不必對這個modCount字段進行序列化,由於沒有意義,modCount主要用於判斷HashMap是否被修改(像put、remove操做的時候,modCount都會自增),對於這種變量,一開始能夠爲任何值,0固然也是能夠(new出來、反序列化出來、或者克隆clone出來的時候都是爲0的),不必持久化其值。this
/** * The number of times this HashMap has been structurally modified * Structural modifications are those that change the number of mappings in * the HashMap or otherwise modify its internal structure (e.g., * rehash). This field is used to make iterators on Collection-views of * the HashMap fail-fast. (See ConcurrentModificationException). */ transient int modCount;
最後,爲何要不被序列化呢,主要是爲了節省存儲空間,其它的感受沒啥好處,可能還有壞處(有些字段可能須要從新計算,初始化什麼的),總的來講,利大於弊。spa
僅僅是示例,具體使用請根據實際狀況:設計
package tmp; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; 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(); } }
結果打印(達到目的,節省存儲空間,成功恢復成原始對象):code
http://stackoverflow.com/questions/910374/why-does-java-have-transient-fields