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

transient與序列化

編輯:JAVA綜合教程

transient與序列化


transient的作用: 修飾實力域,使其從一個類的默認序列化形式中省略(即默認序列化方式不對該字段做寫與讀 存取操作)   應用場景:
  1. 業務需要,不宜做序列化 如銀行密碼等 信息不希望在網絡和磁盤等地方存儲,所以可以用transient 聲明,從而保證相應信息無法從磁盤讀取。(此例源於網上觀點,個人不太贊同)
    1. 默認的序列化方式不適合,采用自定義序列化的方式 例hashMap中對元素的存儲。java 7中hashMap元素的存儲結構為 表 (table)+ 鏈(結點構成的鏈)的存儲結構。其中根據hash(key)求的對應元素在table的索引,並將元素插入此索引處的鏈表。 其中的實例域table 即為transient
          /**
           * The table, resized as necessary. Length MUST Always be a power of two.
           */
          transient Entry[] table = (Entry[]) EMPTY_TABLE;
        那麼問題來了,既然table中存儲著hashMap中的元素信息,為什麼不序列化?   答:不是不序列化,而是不采用默認的序列化。 由於table中元素信息是我們存取關注的,而非table的結構,所以能合理的完成table中所有信息的存取是關鍵。 鑒於table結構過於復雜(其中的鏈表結構為Entry 結點構成的鏈表),若采用默認的序列化方式,會將table的完整結構(包括各鏈表)鏡像一份,如此以來帶來一下弊端: 1. 不僅需要消化大量時間遍歷table結構 2. 占用較多的存儲空間 3. 默認序列化對對象圖做遞歸遍歷當表過大時會發生堆棧溢出,所以避免使用默認的序列化方式。   hashMap中采用序列化存儲過程中遍歷table中元素,並逐一序列化儲存。而在序列化讀取過程中,根據讀出數值還原表結構的方式來完成,從而提高序列化的質量。過程如下:
      private void writeObject(java.io.ObjectOutputStream s)
              throws IOException
          {
              // Write out the threshold, loadfactor, and any hidden stuff
              s.defaultWriteObject();
               ….
                //自定義完成table中信息的存儲
              // Write out keys and values (alternating)
              if (size > 0) {
                  for(Map.Entry e : entrySet0()) {
                      s.writeObject(e.getKey());
                      s.writeObject(e.getValue());
                  }
              }
          }
      
          private static final long serialVersionUID = 362498820763181265L;
      
          /**
           * Reconstitute the {@code HashMap} instance from a stream (i.e.,
           * deserialize it).
           */
          private void readObject(java.io.ObjectInputStream s)
               throws IOException, ClassNotFoundException
          {
              // Read in the threshold (ignored), loadfactor, and any hidden stuff
              s.defaultReadObject();
              ...
              //依次讀取,並還原表結構
              // Read the keys and values, and put the mappings in the HashMap
              for (int i = 0; i < mappings; i++) {
                  K key = (K) s.readObject();
                  V value = (V) s.readObject();
                  putForCreate(key, value);
              }
          } 

      如此,當自定義中實例域存儲機構將復雜,默認序列化方式無法勝任時,可以聲明為transient,並自定義完成該字段中信息的序列化。

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