web-dev-qa-db-ja.com

プリミティブおよびボックス化された値に==を使用する場合、オートボックス化が行われるか、またはボックス化解除が行われます

次のコードがコンパイルされます(Java 8)で:

Integer i1 = 1000;
int i2 = 1000;
boolean compared = (i1 == i2);

しかし、それは何をしますか?

ボックスi1

boolean compared = (i1.intvalue() == i2);

またはボックスi2

boolean compared = (i1 == new Integer(i2));

では、2つのIntegerオブジェクト(参照)ま​​たは2つのint変数を値で比較しますか?

整数クラスは-128から127までの値の内部キャッシュを保持するため、一部の数値では参照比較によって正しい結果が得られることに注意してください(TheLostMindのコメントも参照)。これが、私の例で1000を使用した理由であり、比較の結果ではなく、ボックス化解除/ボックス化について具体的に尋ねる理由です。

53
Thirler

JLS#15.21.1 で定義されています:

等号演算子のオペランドが両方とも数値型であるか、一方が数値型で、もう一方が数値型に変換可能(§5.1.8)である場合、オペランドに対してバイナリ数値プロモーションが実行されます(§5.6.2)。

そして JLS#5.6.2

演算子が2進数の数値昇格をオペランドのペアに適用する場合、各オペランドは数値型に変換可能な値を示す必要があり、次の規則が順番に適用されます。

  • いずれかのオペランドが参照型である場合、そのボックス化解除変換の対象となります[...]

したがって、あなたの質問に答えるために、Integerintにボックス化されていません。

49
assylias

いくつか例を示しましょう:

ケース-1:

       public static void main(String[] args) {
            Integer i1 = 1000;
            int i2 = 1000;
            boolean compared = (i1 == i2);
            System.out.println(compared);
        }

バイトコード:

....
        16: if_icmpne     23 // comparing 2 integers
....

ケース-2:

public static void main(String[] args) {
    Integer i1 = 1000;
    Integer i2 = 1000;
    //int i2 = 1000;
    boolean compared = (i1 == i2);
    System.out.println(compared);
}

バイトコード:

...
     16: if_acmpne     23 // comparing references
....

したがって、Integerint==と比較する場合、Integerintにボックス化解除され、その後比較が行われます。

2 Integersを比較する場合、2 Integersの参照が比較されます。

36
TheLostMind

説明

  1. ==演算子を使用して2つのプリミティブ値を比較すると、オートボクシングは行われません。

  2. ==演算子を使用して2つのオブジェクトを比較する場合、オートボクシングが役割を果たします。

  3. 混合の組み合わせを使用する場合、オブジェクトとプリミティブ型が含まれ、比較は==演算子を使用して行われ、オブジェクトでボックス化解除が行われ、プリミティブ型に変換されます。

適切な例を使用してオートボクシングの詳細を理解するのに役立つ以下のリンクをご覧ください。

参照リンク: http://javarevisited.blogspot.in/2012/07/auto-boxing-and-unboxing-in-Java-be.html

1
karan shah