194
class D {
    public static void main(String args[]) {
        Integer b2=128;
        Integer b3=128;
        System.out.println(b2==b3);
    }
}

出力:

false

class D {
    public static void main(String args[]) {
        Integer b2=127;
        Integer b3=127;
        System.out.println(b2==b3);
    }
}

出力:

true

注:-128から127までの数値は真です。

4

8 に答える 8

238

Javaで数値リテラルをコンパイルし、それを整数(大文字I)に割り当てると、コンパイラーは次のように出力します。

Integer b2 =Integer.valueOf(127)

このコード行は、オートボクシングを使用するときにも生成されます。

valueOf特定の数値が「プール」されるように実装され、128より小さい値に対して同じインスタンスを返します。

java 1.6のソースコードの621行目:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

の値はhigh、systemプロパティを使用して別の値に構成できます。

-Djava.lang.Integer.IntegerCache.high = 999

そのシステムプロパティを使用してプログラムを実行すると、trueが出力されます。

明らかな結論:2つの参照が同一であることに依存することは決してなく、常にそれらを.equals()メソッドと比較してください。

したがってb2.equals(b3)、b2、b3のすべての論理的に等しい値に対してtrueを出力します。

Integerキャッシュはパフォーマンス上の理由からではなく、JLSのセクション5.1.7に準拠するために存在することに注意してください。オブジェクトIDは、-128から127までの値で指定する必要があります。

Integer#valueOf(int)も、この動作を文書化しています。

この方法では、頻繁に要求される値をキャッシュすることで、スペースと時間のパフォーマンスが大幅に向上する可能性があります。このメソッドは、常に-128〜127の範囲の値をキャッシュし、この範囲外の他の値をキャッシュする場合があります。

于 2009-11-09T10:06:18.890 に答える
27

オートボクシングは-128から127をキャッシュします。これはJLS(5.1.7)で指定されています。

ボックス化されている値pがtrue、false、バイト、\u0000から\u007fの範囲の文字、または-128から127までの整数または短い数値の場合、r1とr2を任意の2つのボックス変換の結果とします。 pの。r1==r2の場合は常にそうです。

オブジェクトを処理するときに覚えておくべき簡単なルールは.equals、2つのオブジェクトが「等しい」かどうかを確認する場合に使用==し、同じインスタンスを指しているかどうかを確認する場合に使用します。

于 2009-11-09T10:04:14.143 に答える
11

プリミティブデータ型intを使用すると、どちらの場合も、期待される出力であるtrueが生成されます。

ただし、整数オブジェクトを使用しているため、==演算子の意味は異なります。

オブジェクトのコンテキストでは、==は変数が同じオブジェクト参照を参照しているかどうかを確認します。

オブジェクトの値を比較するには、equals()メソッドを使用する必要があります。

 b2.equals(b1)

これは、b2がb1より小さいか、大きいか、等しいかを示します(詳細についてはAPIを確認してください)

于 2009-11-09T10:09:09.873 に答える
8

Java関連のメモリ最適化です。

メモリを節約するために、Javaは値が次の範囲にあるすべてのラッパーオブジェクトを「再利用」します。

すべてのブール値(trueおよびfalse)

すべてのバイト値

\u0000から\u007fまでのすべての文字値(つまり、10進数で0から127)

-128から127までのすべての短整数値。

于 2016-02-26T07:25:31.523 に答える
4

Integer.javaを見てください。値が-128〜127の場合、キャッシュされたプールが使用されるため(Integer) 1 == (Integer) 1(Integer) 222 != (Integer) 222

 /**
 * Returns an {@code Integer} instance representing the specified
 * {@code int} value.  If a new {@code Integer} instance is not
 * required, this method should generally be used in preference to
 * the constructor {@link #Integer(int)}, as this method is likely
 * to yield significantly better space and time performance by
 * caching frequently requested values.
 *
 * This method will always cache values in the range -128 to 127,
 * inclusive, and may cache other values outside of this range.
 *
 * @param  i an {@code int} value.
 * @return an {@code Integer} instance representing {@code i}.
 * @since  1.5
 */
public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}       
于 2016-02-16T02:05:28.767 に答える
2

他の回答は、観察された効果が観察できる理由を説明していますが、それはプログラマーにとっては本当に重要なことではありません(興味深いことですが、実際のコードを書くときに忘れておくべきことです)。

整数オブジェクトが等しいかどうかを比較するには、equalsメソッドを使用します。

恒等演算子を使用して整数オブジェクトが等しいかどうかを比較しようとしないでください==

いくつかの等しい値が同一のオブジェクトである場合がありますが、これは一般的に信頼されるべきものではありません。

于 2020-06-08T22:54:31.300 に答える
0

値が-128〜127の場合、キャッシュされたプールが使用されます。これは、自動ボクシングの場合にのみ当てはまります。したがって、以下があります。

    public static void main(String[] args) {
        Integer a  = new Integer(100);
        Integer b = new Integer(100);
        System.out.println(a == b);         // false. == compare two instances, they are difference
        System.out.println(a.equals(b));    // true. equals compares the value

        Integer a2 = 100;
        Integer b2 = 100;
        System.out.println(a2 == b2);       // true. auto-boxing uses cached pool between -128/127
        System.out.println(a2.equals(b2));  // true. equals compares the value

        Integer a3 = 129;
        Integer b3 = 129;
        System.out.println(a3 == b3);       // false. not using cached pool
        System.out.println(a3.equals(b3));  // true. equals compares the value
    }
}
于 2022-02-03T20:20:10.537 に答える
-4

この問題は整数に固有のものではないので、私は次のように書きました。私の結論は、APIを誤って使用すると、多くの場合、誤った動作が見られるということです。正しく使用すると、正しい動作が表示されます。

public static void main (String[] args) {
    Byte b1=127;
    Byte b2=127;

    Short s1=127; //incorrect should use Byte
    Short s2=127; //incorrect should use Byte
    Short s3=128;
    Short s4=128;

    Integer i1=127; //incorrect should use Byte
    Integer i2=127; //incorrect should use Byte
    Integer i3=128;
    Integer i4=128;

    Integer i5=32767; //incorrect should use Short
    Integer i6=32767; //incorrect should use Short

    Long l1=127L;           //incorrect should use Byte
    Long l2=127L;           //incorrect should use Byte
    Long l3=13267L;         //incorrect should use Short
    Long l4=32767L;         //incorrect should use Short
    Long l5=2147483647L;    //incorrect should use Integer 
    Long l6=2147483647L;    //incorrect should use Integer
    Long l7=2147483648L;
    Long l8=2147483648L;

    System.out.print(b1==b2); //true  (incorrect) Used API correctly
    System.out.print(s1==s2); //true  (incorrect) Used API incorrectly
    System.out.print(i1==i2); //true  (incorrect) Used API incorrectly
    System.out.print(l1==l2); //true  (incorrect) Used API incorrectly

    System.out.print(s3==s4); //false (correct) Used API correctly
    System.out.print(i3==i4); //false (correct) Used API correctly
    System.out.print(i5==i6); //false (correct) Used API correctly
    System.out.print(l3==l4); //false (correct) Used API correctly
    System.out.print(l7==l8); //false (correct) Used API correctly
    System.out.print(l5==l6); //false (correct) Used API incorrectly

}
于 2012-06-11T08:19:09.020 に答える