なぜ128==128falseが127==127がtrueを比較する場合は整数の包装にはJava?
-
19-09-2019 - |
質問
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ています。
解決
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
の値は、システムプロパティで、別の値に設定することができます。
-Djava.lang.Integer.IntegerCache.high = 999
あなたがそのシステムプロパティを使用してプログラムを実行した場合、それが出力本当!
明白な結論:2つの参照が同じであることに依存していることはありませんが、常に.equals()
方法でそれらを比較。
だから、b2.equals(b3)
はB3、B2のすべての論理的に等しい値に対して真印刷されます。
そのInteger
キャッシュはパフォーマンス上の理由のためにそこにではなく、<のhref = "http://java.sun.com/docs/books/jls/third%5Fedition/html/conversions.htmlに準拠するように注意してください#5.1.7" のrel = "nofollowをnoreferrer"> JLS、セクション5.1.7 の。オブジェクトIDは、包括的に127の値-128のために与えられなければならない。
整数#のvalueOfまた、この動作を文書化する(INT):
この方法では、頻繁に要求された値をキャッシュすることで有意に良好空間と時間のパフォーマンスをもたらす可能性があります。この方法は、常に範囲-128 127、包括的に値をキャッシュする、この範囲外の他の値をキャッシュしてもよい。
他のヒント
自動ボックス化キャッシュ-128-127.ここで指定された環太平洋(5.1.7).
の場合の値 p 八方塞がりがtrueの場合は、falseの場合、バイトは、charの範囲\u0000め\u007f、またはintまたは短期間番号-128と 127しましょうr1及びr2の結果は二つのボクシング変換 のp.いつもの場合r1==r2.
簡単なルールが扱うオブジェクト用 .equals
を確認することができます場合には、二つのオブジェクトと"等価"、 ==
したいときに見た場合のそれと同一のインスタンスとなります。
の両方の場合に真生成するであろう、プリミティブデータ型、int型を使用して、期待される出力
あなたは整数を使用しているので、しかし、==演算子は異なる意味を持っているオブジェクトます。
オブジェクトの文脈では、==変数が同じオブジェクト参照を参照するかどうかをチェックします。
あなたは等号を使用する必要があるオブジェクト()メソッドの値を比較するには 例えばます。
b2.equals(b1)
を超える、B2はB1未満であるかどうかを示す、またはそれに等しいであろう(詳細はAPIを確認してください)
これは、関連するJavaでのメモリの最適化である。
メモリに保存するには、Javaの再利用 "その値は、すべてのラッパーオブジェクト 以下の範囲に該当します:
すべてのブール値(trueとfalse)
すべてのバイト値
\のU0000から全ての文字の値が(10進数で127即ち0)u007fに\
-128から127までのすべての短整数値を
値は-128から127の間であれば、それはキャッシュされたプールを使用します、Integer.javaを見てください、そう(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);
}
私は次のように書きました。私の結論は、あなたが間違って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
}