18
public class Main { 
    /** 
      * @param args the command line arguments */ 
    public static void main(String[] args) { 
        // TODO code application logic here
        int a1 = 1000, a2 = 1000; 
        System.out.println(a1==a2);//=>true 
        Integer b1 = 1000, b2 = 1000;
        System.out.println(b1 == b2);//=>false 
        Integer c1 = 100, c2 = 100; 
        System.out.println(c1 == c2);//=>true 
    }

}

なぜb1 == b2偽とc1 == c2真なのですか?

4

7 に答える 7

38

これを読んでください。

Java は、-128 から 127 の範囲で s のプールを使用します。Integer

つまり、 with を作成IntegerInteger i = 42;、その値が -128 ~ 128 の場合、新しいオブジェクトは作成されませんが、プールから対応するオブジェクトが返されますc1が実際にと同一である理由 はここにありc2ます。

オブジェクトに適用されたときに、値ではなく参照を比較することを知っている==と思います)。

于 2010-07-28T10:14:06.270 に答える
12

正しい答えはすでに与えられています。しかし、私の2セントを追加するだけです:

Integer b1 = 1000, b2 = 1000;

これはひどいコードです。オブジェクトは、コンストラクターまたはファクトリ メソッドを介してオブジェクトとして初期化する必要があります。例えば

 // let java decide if a new object must be created or one is taken from the pool
Integer b1 = Integer.valueOf(1000);

また

 // always use a new object
 Integer b2 = new Integer(1000);

このコード

Integer b1 = 1000, b2 = 1000;

一方、Integer がプリミティブであることを意味しますが、そうではありません。実際に表示されているのはショートカットです

Integer b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000);

Integer は -127 から 127 までのオブジェクトのみをプールするため、この場合は 2 つの新しいオブジェクトが作成されます。したがって、1000 = 1000 ですが、b1 != b2 です。これが、オートボクシングが嫌いな主な理由です。

于 2010-07-28T10:53:47.640 に答える
2

Integer は列挙型のようにいくつかの低い数値用であるため、常に同じインスタンスが存在します。ただし、数値が大きいと Integer の新しいインスタンスが作成され、演算子 == はそれらの参照を比較します

于 2010-07-28T10:14:48.887 に答える
2

ここで答えを見つけることができます:

6番目の回答で最も奇妙な言語機能。

編集:申し訳ありませんが、答えは正確ではありません。ポイントは、== は、Integer で使用する場合、値ではなく参照を比較するということです。しかし、int "==" は等しいことを意味します。

于 2010-07-28T10:13:57.237 に答える
2
  public static Integer valueOf(int i) {
      final int offset = 128;
      if (i >= -128 && i <= 127) { // must cache
          return IntegerCache.cache[i + offset];
      }
       return new Integer(i);
    }

このため、ある場合は真であり、別の場合は偽です!

于 2012-07-13T12:03:09.060 に答える
0

あなたの欲しい答えがここにあります

于 2010-07-28T10:11:32.470 に答える
0

'==' 演算子を使用して等価性チェックを行うときにも自動ボックス化解除が機能する場合は、次のように記述できます。

    Long notNullSafeLong1 = new Long(11L)
    Long notNullSafeLong2 = new Long(22L)
    if ( notNullSafeLong1 == notNullSafeLong2) {
      do suff

これには、== のオーバーライドを実装して、null==someLong が false になり、特殊なケース Null==Null が true になるようにする必要があります。代わりに、 equal() を使用して null をテストする必要があります

    Long notNullSafeLong1 = new Long(11L)
    Long notNullSafeLong2 = new Long(22L)
    if ( (notNullSafeLong1 == null && notNullSafeLong2 == null) || 
      (notNullSafeLong1 != null && notNullSafeLong2 != null & 
        notNullSafeLong1.equals(notNullSafeLong2)) {
      do suff    

これは、最初の例よりも少し冗長です - 自動ボックス化解除が「==」演算子に対して機能していた場合。

于 2013-08-22T11:34:24.230 に答える