26

次のスニペットを検討してください。

    int i = 99999999;
    byte b = 99;
    short s = 9999;
    Integer ii = Integer.valueOf(9); // should be within cache

    System.out.println(new Integer(i) == i); // "true"
    System.out.println(new Integer(b) == b); // "true"
    System.out.println(new Integer(s) == s); // "true"
    System.out.println(new Integer(ii) == ii); // "false"

最後の行が常に出力される理由は明らかです。参照同一性比較"false"を使用しており、オブジェクトが既存のオブジェクトになることは決してありません。==new==

問題は最初の 3 行についてです。これらの比較は、自動アンボックス化されたプリミティブ上にあることが保証されていますか? 代わりにプリミティブが自動ボックス化され、参照同一性比較が実行される場合はありますか? (それはすべてです!)intIntegerfalse

4

2 に答える 2

21

はい。 JLS §5.6.2は、2 進数の昇格のルールを指定します。ある程度:

演算子がバイナリ数値昇格をオペランドのペアに適用する場合、各オペランドは数値型に変換可能な値を示す必要があります。必要に応じてオペランドを変換する拡大変換 (§5.1.2) を使用して、次の規則が順番に適用されます。 :

オペランドのいずれかが参照型の場合、ボックス化解除変換 (§5.1.8) が実行されます。

バイナリ数値昇格は、「数値等価演算子 == および !=」を含むいくつかの数値演算子に適用されます。

JLS §15.21.1 (数値等価演算子 == および !=) は次のように規定しています。

等価演算子のオペランドが両方とも数値型である場合、または一方が数値型で他方が数値型に変換可能 (§5.1.8) である場合、バイナリ数値昇格がオペランドに対して実行されます (§5.6.2)。

対照的に、JLS §15.21.3 (参照等価演算子 == および !=) は以下を提供します。

等価演算子のオペランドが両方とも参照型または null 型の場合、演算はオブジェクト等価です。

これは、ボックス化とボックス化解除の一般的な理解に適合します。つまり、不一致がある場合にのみ行われます。

于 2010-05-14T05:10:35.420 に答える
8

最初に、が参照等値である場合と、数値等値である場合を正確に説明します。 参照等号の条件はもっと簡単なので先に説明します。==

JLS 15.21.3 参照等価演算子==および!=

等価演算子のオペランドが両方とも参照型またはnull型の場合、演算はオブジェクト等価です。

これにより、次のことが説明されます。

System.out.println(new Integer(0) == new Integer(0)); // "false"

両方のオペランドはInteger参照型であり、それが==is 参照等価比較であり、2 つのnewオブジェクトが==互いに決して一致しないため、 が出力されfalseます。

==数値が等しいためには、オペランドの少なくとも 1 つが数値型でなければなりません。これは次のように指定されます。

JLS 15.21.1 数値等価演算子==および!=

等価演算子のオペランドが両方とも数値型である場合、または一方が数値型で他方が数値型に変換可能な場合、オペランドに対してバイナリ数値昇格が実行されます。オペランドの昇格された型がintorlongの場合、整数の等価性テストが実行されます。昇格された型がfloat or double の場合、浮動小数点の等価性テストが実行されます。

バイナリ数値プロモーションでは、値セットの変換とボックス化解除の変換が実行されることに注意してください。

したがって、次の点を考慮してください。

System.out.println(new Integer(0) == 0); // "true"

true次の理由により、これは を出力します。

  • 右側のオペランド数値int型です
  • 左のオペランドは、ボックス化を解除して数値型に変換できますint
  • したがって==、数値等価演算です

概要

  • ==との両方のオペランド!=が参照型の場合、常に参照等価演算になります。
    • オペランドが数値型に変換可能かどうかは問題ではありません
  • オペランドの少なくとも 1 つが数値型の場合、常に数値等価演算になります。
    • 必要に応じて、オペランドの 1 つ (多くても!) で自動ボックス化解除が実行されます

参考文献

関連する質問

于 2010-05-14T06:07:47.270 に答える