程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java中的關鍵字 transient

Java中的關鍵字 transient

編輯:關於JAVA

Java中的關鍵字 transient。本站提示廣大學習愛好者:(Java中的關鍵字 transient)文章只能為提供參考,不一定能成為您想要的結果。以下是Java中的關鍵字 transient正文


先解釋下Java中的對象序列化

在討論transient之前,有必要先搞清楚Java中序列化的含義;

Java中對象的序列化指的是將對象轉換成以字節序列的方式來表示,這些字節序列包括了對象的數據和信息,一個序列化後的對象可以被寫到數據庫或文件中,也可用於網絡傳輸,普通當我們運用緩存cache(內存空間不夠有能夠會本地存儲到硬盤)或近程調用rpc(網絡傳輸)的時分,常常需求讓我們的實體類完成Serializable接口,目的就是為了讓其可序列化。

當然,序列化後的最終目的是為了反序列化,恢復成原先的Java對象,要不然序列化後干嘛呢,所以序列化後的字節序列都是可以恢復成Java對象的,這個進程就是反序列化。

關於transient關鍵字

Java中transient關鍵字的作用,復雜地說,就是讓某些被修飾的成員屬性變量不被序列化,這一看仿佛很好了解,就是不被序列化,那麼什麼狀況下,一個對象的某些字段不需求被序列化呢?假如有如下狀況,可以思索運用關鍵字transient修飾:

1、類中的字段值可以依據其它字段推導出來,如一個長方形類有三個屬性:長度、寬度、面積(示例而已,普通不會這樣設計),那麼在序列化的時分,面積這個屬性就沒必要被序列化了;

2、其它,看詳細業務需求吧,哪些字段不想被序列化;

PS,記得之前看HashMap源碼的時分,發現有個字段是用transient修飾的,我覺得還是有道理的,的確沒必要對這個modCount字段停止序列化,由於沒有意義,modCount次要用於判別HashMap能否被修正(像put、remove操作的時分,modCount都會自增),關於這種變量,一開端可以為任何值,0當然也是可以(new出來、反序列化出來、或許克隆clone出來的時分都是為0的),沒必要耐久化其值。

    /**
     * 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;

最後,為什麼要不被序列化呢,次要是為了節省存儲空間,其它的覺得沒啥益處,能夠還有害處(有些字段能夠需求重新計算,初始化什麼的),總的來說,利大於弊。

舉個例子

僅僅是示例,詳細運用請依據實踐狀況:

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();
    }
}

後果打印(到達目的,節省存儲空間,成功恢復成原始對象):

1.原始對象
width : 3
height : 4
area : 12
2.反序列化後的對象
width : 3
height : 4
area : null
3.恢復成原始對象
width : 3
height : 4
area : 12

參考材料

http://stackoverflow.com/questions/910374/why-does-java-have-transient-fields

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved