Java SEの統合(A):プリミティブラッパークラスのソースコードの解釈

プリミティブ型と参照型:Javaの変数の型は、2つのカテゴリに分けることができます。8つの基本タイプ、すなわち、短い、int型、長い、バイト、文字、float型、ダブル、ブール値がありますが、また、そのパッケージ、例えば整数としての基準の8種類があり、ダブルは好きです。この記事では、これらのプリミティブ型とそのラッパークラスを議論することです。

次のセクションでは、ソースの一部のみを代表的なリストであり、コードのない大きなチャンクが存在しないであろうソースに関する。JDKのバージョン私はJDK1.8_144を使用しています

1 INTEGER(プラスチック)

整数は、パッケージの基本型int型です。以下はその継承システムは、次のとおりです。

ilIpdA.png

整数の番号は、同等の能力を持つ、同等の缶を実装するクラスを継承するだけでなく、間接的に直列化可能であるSerializableインタフェースを実現します。いくつかの他のパッケージタイプに関連する実際の数値は、そのようなシステムを継承しているので、以下に特別な指示がない場合、それは同じ継承システムと整数を意味します。

のは、見てのvalueOf()メソッドにしましょう、そこに3人がIntegerクラス()メソッドでのvalueOfをオーバーロードされますが、最終的に公共の静的な整数のvalueOf(I int型)と呼ばれます。以下は、パブリック静的な整数のvalueOf(int型I)源です:

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
复制代码

直接の場合は、基本的なint型の引数を受け入れ、Integerオブジェクトが裁判官ならば、ここで私はこの[IntegerCache.low、IntegerCache.high]間隔かどうかを判断することに留意すべきである返すことが分かりますキャッシュされた値を返し、この値は低く、絶頂はどのくらいですか?私たちは、IntegerCacheクラスになります:

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }
复制代码

整数これは、クラス、デフォルト値は高い値がjava.lang.Integer.IntegerCache.highプロパティによって設定することができる、127高く、-128の低い値ことを確認することが容易であり、コードから、内部の静的クラスでありますほぼすべての静的コードブロックの論理は、それはクラスローダは、それが何であるの実装の結果を行われる際に言っているのですか?コードのこれらの行を見ます:

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
复制代码

区間[低、ハイト]の値がIntegerオブジェクトを構成し、キャッシュ・アレイに記憶されます。範囲内のこの区間の引数場合のvalueOf()メソッドを振り返るために、この時間は、私は見つかったパラメータの値があれば、[低、ハイト]間隔で、それは、次に、単語次いで、対応するキャッシュ内の整数オブジェクトを返しますこのメソッドは、オブジェクトを作成するオーバーヘッドを減らすこと、あなたがオブジェクトを作成する必要はありませんときに呼び出され、キャッシュオブジェクトを直接使用されます。

そして、なぜそれがとても複雑にすべきですか?Java5が自動シンタックスシュガーボクシングと自動アンボクシングを提供し、この方法は実際にあなたがコメントから見ることができる自動包装サービス(ですので、このメソッドはjava5がそこから始まっので、自動ロードを推論する必要があります)ボックスメカニズムを開梱、整数は非常に人気のあるクラスは、このキャッシュメカニズムで、それぞれの時間はあなたが大幅にオブジェクトの再利用率を改善し、自動または手動の梱包通話時間でオブジェクトを作成する必要はありません、ですが、また提供します作業効率。【-128127]は、より保守的な範囲である結局Intgerオブジェクトは大量のメモリを占有することもあるため、ユーザは、好ましくはあまりjava.lang.Integer.IntegerCache.highを変更することにより、高い値を変更することができるが、上限設定が高すぎる、としばしば大きな値、良いよりももう少し害のキャッシュを使用しない場合。

のは、別の方法intValue(見てみましょう)、この方法は非常に簡単です:

    public int intValue() {
        return value;
    }
复制代码

整数値は、プライベートクラスフィールド、int型であり、実際に自動的に電話を開梱するための方法であり、実際の値を表すことです。

他の方法は、言うことは何もないと(例えばMAX_VALUE、MIN_VALUEなど)の定数、および興味の友達(例えばMAX、MIN、toBinaryStringなど)、最も機能的な方法のいくつかである、独自のアルゴリズムロジックは難しいことではありません見ることができます。

いくつかの他が言うことではない、整数のソースを理解した後、他の人が理解することは困難ではありません。

自動ボクシングとアンボクシング2自動

オートボクシングと自動アンボクシングは、我々は比較する必要があるときに提供シンタックスシュガーのJava5で、プリミティブ型とラッパークラス間の割り当てや他の操作、コンパイラが自動的に私たちは型キャストするのに役立ちます、ボクシングは、基本的なタイプですパッケージ型への変換は、プロセスをアンパックすることは対照的です。たとえば、私たちは、次のコードを持っています:

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    int a = 1, b = 2, c = 3;
    list.add(a);
    list.add(b);
    list.add(c);
}
复制代码

次のようにコンパイルされたコンテンツの.classファイル(実際の.classバイトコードファイルがあるべきで、トランスコーディングを行うが、閲覧を容易にするために、それは自分の順番のフォームは、Javaコードになっただろう)。

public static void main(String[] var0) {
    ArrayList var1 = new ArrayList();
    byte var2 = 1;
    byte var3 = 2;
    byte var4 = 3;
    var1.add(Integer.valueOf(var2));
    var1.add(Integer.valueOf(var3));
    var1.add(Integer.valueOf(var4));
}
复制代码

ここでボクシングの操作が発生すると、コンパイラは、私たちは(コンテナ型パラメータは基本的な型にすることはできません)容器の種類に合わせて、int型整数のリストを変換するInteger.valueOf()メソッドを呼び出すのに役立ちます。

アンパックも同様であるが、反対方向と梱包、値は基本的なタイプの包装の種類に割り当てられた場合、一般的に、例えば、発生します。

Integer a = 1;
int b = a; //自动拆箱
复制代码

開梱されていない場合、上記のコードは確かに種類が一致しないため、コンパイルしない、と強いターンされていません。

自動ボクシングとアンボクシングより多くのコンテンツについて、インターネットは情報(非常に、非常に多くの)をたくさん持っている、興味を持って友人が検索を検索するオンライン行くことができるお勧めします。

3それをパッケージの基本的なタイプまたは種類を選択しますか?

まずは、基本的な原則を定義してみましょう:シーンは基本タイプとパッケージタイプのいずれかを使用することができない場合は、別のものを選択することができます。例えば、ジェネリック型パラメータは、あなたが何のためらいを持っていない、パッケージの直接の使用は、それを入力し、コンテナの基本的な型にすることはできません。

両方のタイプが用意されていた場合、基本的なタイプは、以下の三つの主要な理由を使用することをお勧めします。

  1. パッキングタイプあなたは状況があってもキャッシュがオブジェクトを作成する時のオーバーヘッドを保存しますが、スペースのオーバーヘッドがまだある、オブジェクトを作成する必要がある値を使用したいクラスで、最初のオブジェクトは、オブジェクトが含まれ、オブジェクトインスタンスのデータ充填、しかし、我々は唯一の整数のみインスタンスのデータを必要とする実際には、我々は唯一の唯一の値値フィールドに必要な、それは、プリミティブ型intの使用は数回しか基本的なタイプの空間の4つのバイトを占め、およびオブジェクトを使用する必要が言うことですスペース(あなたが計算することができます)。

  2. 次の記事1、そのため、その使用は時々持っているとき、幸い数、サービスロジックとき錯体(またはプログラマが時間の上に書かれたコードを書くことヌルにヌル可能な目標値決意があります)、それはかつて、それは非常に可能性がヌルポインタ例外でない場合は厳密なテストで行方不明、欠場するのは非常に簡単で、実際にそれをテストすることはできません。

  3. 比較は時々混乱作るとき、我々は例を与える包装作業は、次のコードがあるとします。

        public static void main(String[] args) {
            Integer d = 220;  
            Integer e = 220;
            int f = 220;
            System.out.println(d == e);
            System.out.println(e == f);
        }
    复制代码

    あなたは、このような問題が発生していない場合、結果は無意識のうちに実行され、真の、真であると言うかもしれないが、実際には、結果の出力は、真falseです。なぜ?まず比較のため、d及びeは、220が実際にそれらに割り当てられた時間内に発生した自動包装を通してIntegerオブジェクト、実際にはむしろ実際の値よりも、参照==値と直接比較、すなわち、呼び出していますvalueOf上()メソッドは、デフォルトのキャッシュを超え220の範囲ながら、基準のAとBの両方が確実に等しくない場合、それは出力偽し、新しいIntergeオブジェクトを作成します。第2の比較では、fは、基本的なタイプで、この場合には、自動的に開梱起こり、実際に基本的な変数タイプ== int型の両側に、直接比較、出力結果がtrueになります問題はありません。

このようなジェネリック型パラメータのコンテナとしての基本的な型を使用することができない場合、彼らは基本的な型を使用することができれば、要するに、それが唯一の梱包材を使用、むしろパッケージよりも基本的な型を使用するのが最適です。

4まとめ

この記事では、インテグレ包装、そのソースコードの簡単な分析を説明し、その実装は非常に似ている理由を分析するので、保証の基本的なクラスの他のタイプに何の楽しみの導入を繰り返していない理由はありません。また、簡単に自動包装と開梱自動について議論し、この機能を不適切に使用した場合、開発の効率化が、問題を改善するためにプログラマが混乱引き起こす可能性のために便利ですが、それの長所と短所を検討しました。私はテキストの基本的な種類と原因を使用する傾向が基本タイプとパッケージタイプ、間の選択はまた、より詳細に説明します。

おすすめ

転載: juejin.im/post/5d6e8091518825753553d95c