これらの興味深いコード(3) - QinjianchijiaのArrayList

先週はグループではほとんどの友人に尋ねtransientやっているキーワード。この記事では説明するには、この機会になりますtransientのArrayListの内部における役割とアプリケーションを。

ジャワの過渡レッツ・トークシリアライズを理解するために。

レビューのシリアライズ

いわゆるシリアル化手段、バイトのストリームにオブジェクトの機構。同様に、デシリアライゼーションは、オブジェクトへのバイトストリームを指します。

直列化可能

  • Javaオブジェクトの場合、JDK実装のシーケンスの場合。オブジェクトが実装する必要がjava.io.Serializableインターフェイスを。
  • あなたが使用されてもよいObjectOutputStream()し、ObjectInputStream()オブジェクトが直列化および非直列化されます。
  • 呼び出しの一連のときwriteObject()の方法は、オブジェクトは、バイトストリームを変換することです。
  • デシリアライズ時間が呼び出すreadObject()メソッド、オブジェクトにバイトストリームを。
  • Javaのデシリアライゼーション時間はバイトストリームチェックするserialVersionUIDオブジェクトのserialVersionUID時間と一致します。そうでない場合には、スローされますInvalidClassException例外を。公式には強く、オブジェクトの固定シーケンスを指定することをお勧めしますserialVersionUIDそれ以外の場合は、仮想クラスの機会ダイジェストアルゴリズムによって生成された情報に基づいて、その仮想マシンの生成がするとき、私たちは、クラスのパラメータを変更するとserialVersionUID変わります。
  • transientキーワードは、変数が変更されないであろうバイトストリームとしてシリアル化され

レビューのArrayList

図1に示すように、ArrayListには、アレイの実現に基づいて動的配列、自動2をサポートする自動増加容量、ArrayListのスレッドセーフな3、ArrayListの実装シリアライズ、支持シリアライゼーションであります

Qinjianchijia

ArrayListのは、上記に基づいており、我々は、実装の配列についての話、我々はソースを見て:

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */

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

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;
复制代码

いくつかの重要なメッセージがあります。

  • ArraryListこれはからelementDataデータ・ストレージ・オブジェクトである、ダイナミックアレイです。
  • この配列は、実際にこのデータを格納するための配列を変更するための過渡を使用しました。
  • アレイ容量のArrayListの等しい長さ。ArrayListの中の要素の数よりもむしろ。
  • ArrayListのサイズは動的でない配列の長さの要素の数を指します。
  • 過渡大きさは、それをシリアル化することができ、変更されていません。

これは、それがあったか、です。データを格納するためのArrayListの配列は、実際にシリアル化を必要としないのですか?

黒

Moのパニックは、私たちはコードの下を見続けています。私たちは、直列化およびオブジェクトのデシリアライズはのwriteObject()とメソッドを呼び出すことにより、完成のreadObject()である上記述べてきた、我々はそれが、ArrayListには、コードを見ての彼らの二つの方法を実現しました。

        /**
         * 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();
                }
            }
        }
复制代码

注のwriteObject()メソッドで、その、

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

複数のオブジェクトのいくつかのシーケンスインデックスとシリアル化の需要、。

ときに読書は次のとおりです。

     for (int i=0; i<size; i++) {
          a[i] = s.readObject();
     }
复制代码

いくつかの読書は、いくつかあります。

要約すると:

  • transient変更された変数はシリアライズされません。
  • ArrayListの基礎となる配列がelementDataされているtransient直接シリアル化しない、修飾されました。
  • 要素のArrayList、ArrayListの書き換えのシーケンスを実現するためにwriteObject()、およびreadObject()方法を。
  • アレイの需要配列のみを配列データの存在ではなく、全体の配列elementDataアレイ。

どのくらい、どのくらいのシリアライズ、本当に倹約のArrayList。

興味深いコードシリーズ

これらの興味深いコード(A) - 少し孟Tomcatのスレッドプール

これらの興味深いコード(2) - Tomcatのクラスローダの親に聞いていません

おすすめ

転載: juejin.im/post/5de8d7bae51d4557ed5419b5