ボックス化されたプリミティブ Integer を次のような定数と比較すると、次のようになることがわかります。
Integer a = 4;
if (a < 5)
a
自動的にボックス化解除され、比較が機能します。
しかし、2 つのボックスを比較してIntegers
、等しいか、より小さいかより大きいかを比較したい場合はどうなるでしょうか?
Integer a = 4;
Integer b = 5;
if (a == b)
上記のコードを実行すると、同じオブジェクトであるかどうかがチェックされますか、それともその場合は自動的にアンボックスされますか?
以下についてはどうでしょうか:
Integer a = 4;
Integer b = 5;
if (a < b)
?
ベストアンサー1
いいえ、Integer、Longなどの間の==は参照の等価性をチェックします。つまり、
Integer x = ...;
Integer y = ...;
System.out.println(x == y);
これによりx
、 と が等しいオブジェクトではなく同じオブジェクトy
を参照しているかどうかがチェックされます。
それで
Integer x = new Integer(10);
Integer y = new Integer(10);
System.out.println(x == y);
は必ず出力されますfalse
。「小さな」自動ボックス化された値のインターンにより、トリッキーな結果が生じる可能性があります。
Integer x = 10;
Integer y = 10;
System.out.println(x == y);
true
ボクシングのルールにより、これは印刷されます(JLSセクション5.1.7)。依然として参照の等価性が使用されていますが、参照は実際に等価です。
ボックス化される値 p が -128 から 127 までの int 型の整数リテラル (§3.10.1)、または true または false のブール値リテラル (§3.10.3)、または '\u0000' から '\u007f' までの文字リテラル (§3.10.4) である場合、a と b を p の任意の 2 つのボックス化変換の結果とします。常に a == b となります。
個人的には以下を使用します:
if (x.intValue() == y.intValue())
または
if (x.equals(y))
ご指摘のとおり、ラッパー型 ( など) と数値型 ( など) を比較する場合、Integer
ラッパーLong
型int
のlong
値はボックス化解除され、関係するプリミティブ値にテストが適用されます。
これは、2進数値昇格の一部として発生します(JLSセクション5.6.2) それぞれの演算子のドキュメントを見て、それが適用されているかどうかを確認してください。たとえば、および ( ) のドキュメント==
から!=
、JLS15.21.1):
等価演算子のオペランドが両方とも数値型である場合、または一方が数値型でもう一方が数値型に変換可能である場合 (§5.1.8)、オペランドに対してバイナリ数値昇格が実行されます (§5.6.2)。
および<
、、および(<=
>
>=
JLS15.20.1)
数値比較演算子の各オペランドの型は、プリミティブ数値型に変換可能な型 (§5.1.8) でなければなりません。そうでない場合は、コンパイル時エラーが発生します。オペランドに対してバイナリ数値昇格が実行されます (§5.6.2)。オペランドの昇格された型が int または long の場合は、符号付き整数の比較が実行されます。この昇格された型が float または double の場合は、浮動小数点の比較が実行されます。
どちらの型も数値型ではない状況では、これらはすべて考慮されないことに注意してください。