1. ホーム
  2. java

[解決済み] Javaで整数のラッパーを比較するとき、128==128は偽で、127==127は真なのはなぜですか?

2022-04-22 11:51:32

疑問点

class D {
    public static void main(String args[]) {
        Integer b2=128;
        Integer b3=128;
        System.out.println(b2==b3);
    }
}

出力します。

false


class D {
    public static void main(String args[]) {
        Integer b2=127;
        Integer b3=127;
        System.out.println(b2==b3);
    }
}

出力します。

true

注:-128から127までの数値は真となる。

解決方法は?

Javaで数値リテラルをコンパイルしてIntegerに代入すると(大文字の I ) をコンパイラが出力します。

Integer b2 =Integer.valueOf(127)

このコード行は、オートボックスを使用した場合にも生成されます。

valueOf は、特定の数値がプールされるように実装されており、128より小さい値に対して同じインスタンスを返します。

java 1.6ソースコード621行目より。

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

の値は high は、システムプロパティで、別の値に設定することができます。

<ブロッククオート

-Djava.lang.Integer.IntegerCache.high=999

そのシステムプロパティでプログラムを実行すると、trueが出力されます!

明らかな結論は、2つの参照が同一であることを当てにせず、常に .equals() メソッドを使用します。

そこで b2.equals(b3) は論理的に等しいb2,b3の値すべてに対してtrueと表示します。

なお Integer キャッシュがあるのはパフォーマンスのためではなく、むしろ JLS、セクション 5.1.7 オブジェクトの識別は -128 から 127 までの値に対して行わなければなりません。

整数#valueOf(int) もこの動作を記録しています。

このメソッドは、頻繁に要求される値をキャッシュすることで、空間と時間のパフォーマンスを大幅に向上させることができます。このメソッドは常に -128 から 127 までの範囲の値をキャッシュし、 この範囲外の値もキャッシュすることがあります。