TL; DR
Javaはボックス化されたIntegerインスタンスをから-128
にキャッシュし127
ます。を使用==
して値の代わりにオブジェクト参照を比較しているので、キャッシュされたオブジェクトのみが一致します。ボックス化されていないプリミティブ値を使用するか、オブジェクトを比較するために使用します。long
.equals()
Long
長い(しゃれた)バージョン
Long変数と127より大きい値の比較に問題があるのはなぜですか?上記の変数のデータ型がプリミティブ(ロング)の場合、コードはすべての値に対して機能します。
Javaは、-128〜127の範囲の整数オブジェクトインスタンスをキャッシュします。それは言った:
- N Long変数に値
127
(cached)を設定すると、同じオブジェクトインスタンスがすべての参照によってポイントされます。(N変数、1インスタンス)
- N変数に値を設定すると
128
(キャッシュされない)、すべての参照によってポイントされるオブジェクトインスタンスが作成されます。(N変数、Nインスタンス)
これが理由です:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
これを出力します:
真
偽
以下のために127Lの値は、両方の参考文献(val1とVAL2)メモリ内の同じオブジェクト・インスタンスへのポイント(キャッシュ)するので、それは返しtrue
。
一方、128の値の場合、メモリにキャッシュされるインスタンスがないため、ボックス化された値の新しい割り当てに対して新しいインスタンスが作成され、2つの異なるインスタンス(val3とval4によってポイントされる)になりfalse
、それらの間の比較。
これは、プリミティブ値ではなく2つのLong
オブジェクト参照を演算子で比較しているためにのみ発生します。このキャッシュメカニズムがなければ、これらの比較は常に失敗するため、ここでの本当の問題は、ボックス化された値と演算子を比較することです。long
==
==
これらの変数をプリミティブlong
型に変更すると、これを防ぐLong
ことができますが、オブジェクトを使用してコードを維持する必要がある場合は、次の方法でこれらの比較を安全に行うことができます。
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(キャストの場合でも、適切なnullチェックが必要です)
IMO、オブジェクト比較を処理するときは常に.equals()メソッドを使用することをお勧めします。
参照リンク:
.longValue()
。