ホームページ  >  記事  >  Java  >  Java 自動ボックス化、自動アンボックス化、および整数キャッシュの使用方法

Java 自動ボックス化、自動アンボックス化、および整数キャッシュの使用方法

WBOY
WBOY転載
2023-04-24 22:28:121594ブラウズ

1. はじめに

自動ボックス化と自動アンボックス化とは何ですか?整数キャッシュとは何ですか?彼らの間にはどんな関係があるのでしょうか?

まず質問を見てみましょう。

Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a==b);
Integer c = 1;
Integer d = 1;
System.out.println(c==d);
Integer e = 128;
Integer f = 128;
System.out.println(e==f);

最初に答えて、後で答えを見てください。

答えは false true false です。正しいですか?

1 つの部分が登場したので、一緒に知識ポイントを共有しましょう

2. パッケージング クラス

Java には 8 つの基本データ型があり、3 つに分類できます。カテゴリ:

  • 文字型: char

  • ブール型: boolean

  • 数値型: byte short int long float double

パッケージ化クラスは、Java の 3 つの主要な機能であるカプセル化、継承、ポリモーフィズムを使用できるように、8 つの基本データ型をクラスにラップします。対応関係は次のとおりです。

#基本データ型対応するパッケージング クラス ## byteshortint#ロング#フロート#フロートDoubleBoolean# #Character3. 自動ボックス化と自動アンボックス化
Byte
Short
Integer
ロング
# double
boolean
char
数値型に対応する 6 つのパッケージ化クラスはすべて Number クラスを継承します。
8 つの基本データ型は 8 つのパッケージング クラスに対応しますが、それらはどのようにデータ変換を実行するのでしょうか?

//基本数据类型转包装类
//1.有参构造
Integer a = new Integer(1);
//2.实际上,有参构造的参数也可以是字符串,不过要使用正确的数据,“123abc”不可能会转换为Integer类型
Integer b = new Integer("123");
//3.valueOf()
Integer c = Integer.valueOf(123);
//包装类转基本数据类型(xxxValue()  float是floatValue() double是doubleValue())
int d = a.intValue();

上記の形式は認知と比較的一致しています。オブジェクトを取得するには、new を使用するか、特定のメソッドを呼び出します。値を取得するには、オブジェクトの特定の属性を呼び出します。

Java 5.0 以降では、自動ボックス化と自動アンボックス化という新しい機能が追加され、それほど面倒なことは必要ありません。実際、この 2 つの概念は非常に理解しやすいものです。

int a = 10;
Integer b = a;  //自动装箱
int c = b;  //自动拆箱

一見すると、オブジェクト=数値の形式は認識に準拠していませんが、自動ボックス化と自動アンボックス化の助けを借りて実現できます。実際、コンパイラは依然として valueOf() と xxxValue() を利用してこれを実装しています。

valueOf() ソース コードを見てみましょう。

/**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@link #Integer(int)}, as this method is likely
     * to yield significantly better space and time performance by
     * caching frequently requested values.
     *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

valueOf() は単純に Integer オブジェクトを返すのではなく、まず判定を行います 入力データが一定の範囲に一致した場合に特定のオブジェクトを返します コメントからその範囲 デフォルトは [ -128,127] であり、それより大きな範囲になる場合があります。この範囲を超えると、新しいオブジェクトが返されます。 IntegerCache データは Integer のキャッシュです。

4. 整数キャッシュ

数値計算は日常生活で頻繁に使用されます。新しい整数オブジェクトを取得し続けるとオーバーヘッドが非常に大きくなります。そのため、Java は新しい整数オブジェクトを自動的に生成します。プログラムの実行時に静的配列がキャッシュとして使用されます。Integer に対応するデフォルトのキャッシュ配列範囲は [-128,127] です。データがこの範囲内にある限り、対応するオブジェクトをキャッシュから取得できます。

IntegerCache のソース コードを見てください。

/**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */
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() {}
}

ご覧のとおり、IntegerCache は Integer の静的な内部クラスです。valueOf() によって呼び出される IntegerCache.cache は配列オブジェクトです。配列のサイズは、デフォルトは [- 128, 127] ですが、もちろん (コメントによると) この範囲は JVM を通じて変更することもできます (これは理解できません)。次に、配列内の各要素に Integer オブジェクトが割り当てられ、キャッシュが形成されます。

配列キャッシュがあります。つまり、値が [-128,127] にある場合、valueOf() または自動ボックス化を使用して作成された Integer オブジェクトが配列から取り出されるので、オブジェクトはまったく同じです。 new を使用するか、この範囲を超える場合は、オブジェクトを再作成する必要があります。

もちろん、Integer だけがキャッシュ メカニズムを持っているわけではありません。Byte、Short、Long、Character のすべてにキャッシュ メカニズムがあります。 Byte、Short、Integer、Long の範囲は -128 ~ 127、Character の範囲は 0 ~ 127 です。

5. 質問に答えてください

Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a==b);
Integer c = 1;
Integer d = 1;
System.out.println(c==d);
Integer e = 128;
Integer f = 128;
System.out.println(e==f);

1. new で作成された 2 つのオブジェクトが同じ値であっても、それらは異なるメモリ アドレスを指しています。比較に == を使用すると false が返されます

2. 自動ボックス化およびキャッシュ メカニズム。2 つのオブジェクトは実際には同じであり、返される結果は true

3. キャッシュ範囲を超えると、実行中に新しいオブジェクトになります。この 2 つのオブジェクトが一致する場合、オブジェクトが異なります。結果は false を返します

以上がJava 自動ボックス化、自動アンボックス化、および整数キャッシュの使用方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。