<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java關(guān)鍵字transient

          共 9400字,需瀏覽 19分鐘

           ·

          2021-08-23 16:12

          上一篇:深夜看了張一鳴的微博,讓我越想越后怕

          作者:小丸子的呆地
          鏈接:https://www.jianshu.com/p/db184d3acff8

          用transient聲明一個實例變量,當對象存儲時,它的值不需要維持。

          作用

          Java的serialization提供了一種持久化對象實例的機制。當持久化對象時,可能有一個特殊的對象數(shù)據(jù)成員,我們不想用serialization機制來保存它。為了在一個特定對象的一個域上關(guān)閉serialization,可以在這個域前加上關(guān)鍵字transient。當一個對象被序列化的時候,transient型變量的值不包括在序列化的表示中,然而非transient型的變量是被包括進去的。

          驗證

          package com.qjk;
          import java.io.*;
          public class TestTransient {

              static class User implements Serializable {
                  String name;
                  int age;
                  transient int transient_age;
                  String sex;
              }

              public static void main(String[] args) throws IOException, ClassNotFoundException {
                  User user = new User();
                  user.age = 12;
                  user.transient_age = 12;
                  user.name = "小丸子";
                  user.sex = "nv";

                  System.out.println("age:" + user.age);
                  System.out.println("transient_age:" + user.transient_age);
                  System.out.println("name:" + user.name);
                  System.out.println("sex:" + user.sex);

                  System.out.println("----------------序列化+反序列化----------------");

                  // 序列化后寫入緩存
                  ByteArrayOutputStream baos = new ByteArrayOutputStream();
                  ObjectOutputStream oos = new ObjectOutputStream(baos);
                  oos.writeObject(user);
                  oos.flush();
                  oos.close();

                  byte[] buf = baos.toByteArray();
                  // 從緩存中讀取并執(zhí)行反序列化
                  ByteArrayInputStream bais = new ByteArrayInputStream(buf);
                  ObjectInputStream ois = new ObjectInputStream(bais);

                  User u = (User) ois.readObject();

                  System.out.println("age:" + u.age);
                  System.out.println("transient_age:" + u.transient_age);
                  System.out.println("name:" + u.name);
                  System.out.println("sex:" + u.sex);

              }
          }

          結(jié)果輸出

          age:12
          transient_age:12
          name:小丸子
          sex:nv
          ----------------序列化+反序列化----------------
          age:12
          transient_age:0
          name:小丸子
          sex:nv


          擴展

          Exteranlizable

          Java序列化提供兩種方式。一種是實現(xiàn)Serializable接口。另一種是實現(xiàn)Exteranlizable接口。Externalizable接口是繼承于Serializable ,需要重寫writeExternal和readExternal方法,它的效率比Serializable高一些,并且可以決定哪些屬性需要序列化(即使是transient修飾的),但是對大量對象,或者重復(fù)對象,則效率低。

          ArrayList中的transient

          下面是ArrayList中的一段代碼

              /**
               * ArrayList 的元素存儲在其中的數(shù)組緩沖區(qū)。ArrayList 的容量就是這個數(shù)組緩沖
               * 區(qū)的長度。添加第一個元素時,任何帶有 elementData == 
               * DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的空 ArrayList 都將擴展為 
               * DEFAULT_CAPACITY。
               */

              transient Object[] elementData; // non-private to simplify nested class access

          ArrayList提供了自定義的wirteObject和readObject方法:

              /**
               * Save the state of the <tt>ArrayList</tt> instance to a stream (that
               * is, serialize it).
               *
               * @serialData The length of the array backing the <tt>ArrayList</tt>
               *             instance is emitted (int), followed by all of its elements
               *             (each an <tt>Object</tt>) in the proper order.
               */

              private void writeObject(java.io.ObjectOutputStream s)
                  throws java.io.IOException
          {
                  // Write out element count, and any hidden stuff
                  int expectedModCount = modCount;
                  s.defaultWriteObject();

                  // Write out size as capacity for behavioural compatibility with clone()
                  s.writeInt(size);

                  // Write out all elements in the proper order.
                  for (int i=0; i<size; i++) {
                      s.writeObject(elementData[i]);
                  }

                  if (modCount != expectedModCount) {
                      throw new ConcurrentModificationException();
                  }
              }

              /**
               * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
               * deserialize it).
               */

              private void readObject(java.io.ObjectInputStream s)
                  throws java.io.IOException, ClassNotFoundException 
          {
                  elementData = EMPTY_ELEMENTDATA;

                  // Read in size, and any hidden stuff
                  s.defaultReadObject();

                  // Read in capacity
                  s.readInt(); // ignored

                  if (size > 0) {
                      // be like clone(), allocate array based upon size not capacity
                      int capacity = calculateCapacity(elementData, size);
                      SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);
                      ensureCapacityInternal(size);

                      Object[] a = elementData;
                      // Read in all elements in the proper order.
                      for (int i=0; i<size; i++) {
                          a[i] = s.readObject();
                      }
                  }
              }

          我理解這里定義elementData為transient是為了防止數(shù)據(jù)重復(fù)被寫入磁盤,節(jié)省空間。

          如果對象聲明了readObject和writeObject方法,對象在被序列化的時候會執(zhí)行對象的readObject和writeObject方法。

          靜態(tài)屬性

          靜態(tài)屬性,無論是否被transient修飾,都不會被序列化。

          感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!小編到你上高速。

              · END ·
          最后,關(guān)注公眾號互聯(lián)網(wǎng)架構(gòu)師,在后臺回復(fù):2T,可以獲取我整理的 Java 系列面試題和答案,非常齊全


          正文結(jié)束


          推薦閱讀 ↓↓↓

          1.不認命,從10年流水線工人,到谷歌上班的程序媛,一位湖南妹子的勵志故事

          2.如何才能成為優(yōu)秀的架構(gòu)師?

          3.從零開始搭建創(chuàng)業(yè)公司后臺技術(shù)棧

          4.程序員一般可以從什么平臺接私活?

          5.37歲程序員被裁,120天沒找到工作,無奈去小公司,結(jié)果懵了...

          6.IntelliJ IDEA 2019.3 首個最新訪問版本發(fā)布,新特性搶先看

          7.這封“領(lǐng)導(dǎo)痛批95后下屬”的郵件,句句扎心!

          8.15張圖看懂瞎忙和高效的區(qū)別!

          一個人學(xué)習(xí)、工作很迷茫?


          點擊「閱讀原文」加入我們的小圈子!

          瀏覽 58
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一区一区国家精品 | 天天撸一撸视频 | 欧美19p| 大白屁股日本女人视频 | 婷婷五月天AV |