9

2 つのコードを比較しています。初め

Integer i=3;
Integer j=3;
if(i==j)
   System.out.println("i==j");  //prints i==j              

2番、

Integer i=3;
Integer j=new Integer(3);
if(i==j)
   System.out.println("i==j"); // does not print

最初のスニペットでなぜi==j印刷されているのか疑問に思っていますか? 参照は異なるべきではありませんか?

4

9 に答える 9

18

それはボクシングの仕組みに関係しています。JLS セクション 5.1.7から:

ボックス化された値 p が true、false、\u0000 ~ \u007f の範囲のバイト、または char、または -128 ~ 127 (両端を含む) の int または short の数値である場合、r1 および r2 を次の結果とします。 p の任意の 2 つのボクシング変換。r1 == r2 は常にそうです。

基本的に、Java 実装は、適切に小さい値のボックス化された表現をキャッシュする必要があり、さらにキャッシュすることもできます。演算子は==参照を比較しているだけなので、2 つの変数が同じオブジェクトを参照しているかどうかを明確に検出しています。2 番目のコード スニペットでは、new Integer(3)以前に作成されたものと同じ参照ではないことは間違いないため、間違いなくそうではありません...常に新しいオブジェクトが作成されます。

上記の規則により、このコードは常に同じ結果を返す必要があります。

Integer x = 127;
Integer y = 127;
System.out.println(x == y); // Guarantee to print true

これはどちらの方法でもかまいません:

Integer x = 128;
Integer y = 128;
System.out.println(x == y); // Might print true, might print false
于 2013-07-05T17:35:35.807 に答える
6

Java は -128 から 127 までの整数をプールするため、両方の参照は同じです。

Integer i=3;
Integer j=3;

これによりオートボクシングが行われ、3 は Integer 3 に変換されます。つまり、i は定数プールにある Integer オブジェクトを参照しているため、j=3 を実行すると、i と同じ参照が j に割り当てられます。

以下のコードに対して:

Integer j=new Integer(3);

常にヒープ内に新しい整数が作成されます。これはプールされません。したがって、両方の参照が異なるオブジェクトを参照していることがわかります。その結果、

Integer i=3;
Integer j=new Integer(3);
if(i==j)
   System.out.println("i==j"); // **does not print**
于 2013-07-05T17:34:52.593 に答える
3
Integer i=3;
Integer j=3;
if(i==j)System.out.println("i==j");

ここで、3は自動ボックス化されているため、同じij指していIntegerます。

Integer i=3;
Integer j=new Integer(3);
if(i==j)System.out.println("i==j"); // does not print

ここではi、auto-boxed を指しているのIntegerに対しj、newIntegerを指しているため、equals==演算子のテストに失敗する参照があります。

しかし、ここでさらに考える必要があります。

Integer i=300;
Integer j=300;
if(i!=j)System.out.println("i!=j"); // prints i!=j

なんで?自動ボクシングIntegerは -128 から 127 の間のインスタンスのみを共有するためです。ただし、この動作は Java 実装によって異なる場合があります。

于 2013-07-05T17:40:57.077 に答える
1

いいえ、そうすべきではありません。なぜなら、Java はオートボクシング時に小さな数値に対して事前に作成された Integer オブジェクトを使用できるからです。

于 2013-07-05T17:34:19.820 に答える
0

In a similar fashion to strings, when autoboxing is used, such as in

Integer i = 3;
Integer j = 3;

Java can draw from a pool of prefabricated objects. In the case of j, there's already an Integer instance representing the value of 3 in the pool, so it draws from that. Thus, i and j point to the same thing, thus i == j.

In your second example, you're explicitly instantiating a new Integer object for j, so i and j point to different objects, thus i != j.

于 2013-07-05T17:37:58.953 に答える
0

インタープリター/JIT オプティマイザーは、すべての 3 を同じボックスに入れることができます。ただし、「新規」を強制すると、別のアドレスが取得されます。

試す

 j=8; // after initialization of i and j

次に、最初のバージョンで変更された j のアドレスを確認します。

于 2013-07-05T17:35:32.993 に答える
0

2番目のコードでは、最初の整数が自動ボックス化されているのに対し、2番目の整数は自動ボックス化されていないためです。

これは、新しい Integer インスタンスがその場で作成されていることを意味します。これら 2 つのオブジェクト インスタンスは異なります。2 つのインスタンスは実際にはメモリの異なる部分であるため、等価性チェックは false を返します。

于 2013-07-05T17:33:53.557 に答える