これらのコード行が異なる値を返す理由はわかりません。
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
出力は次のとおりです。
true
false
true
最初のものがtrue
を返し、2番目のものがfalse
を返すのはなぜですか? 127
と128
の間に私が知らない何か違うものはありますか? (もちろん、127
<128
であることは知っています。)
また、なぜ3番目のものはtrue
を返すのですか?
私は答えを読みました この質問の ですが、true
を返す方法と、2行目のコードがfalse
を返す理由がまだわかりませんでした。
ここには顕著な違いがあります。
valueOf
はInteger
オブジェクトを返し、その値は-128〜127の間にキャッシュされます。これが、最初の値がtrue
-キャッシュされている-と2番目の値を返す理由ですfalse
を返します-128はキャッシュされた値ではないため、2つの別個のInteger
インスタンスを取得しています。
注意することは重要です参照をInteger#valueOf
と比較していること、そしてキャッシュがサポートする値よりも大きい値を比較している場合、not解析された値が同等であっても、true
に評価されます(ケースの例:Integer.valueOf(128) == Integer.valueOf(128)
)。 代わりにequals()
を使用する必要があります。
parseInt
はプリミティブint
を返しています。これが3番目の値がtrue
を返す理由です-128 == 128
が評価され、もちろんtrue
です。
さて、3番目の結果true
がたまたま生成されました:
ボックス化解除の変換が発生します 使用している等価演算子と使用しているデータ型に関して-つまり、int
とInteger
。もちろん、右側のInteger
からvalueOf
を取得しています。
変換後、2つのプリミティブint
値を比較しています。比較は、プリミティブに関して期待どおりに行われるため、128
と128
を比較することになります。
Integer
クラスには静的キャッシュがあり、256個の特別なInteger
オブジェクトを保存します--128〜127の間のすべての値に1つ。これを念頭に置いて、これら3つの違いを考慮してください。
_new Integer(123);
_
これは(明らかに)真新しいInteger
オブジェクトを作成します。
_Integer.parseInt("123");
_
これは、int
を解析した後、String
プリミティブ値を返します。
_Integer.valueOf("123");
_
これは他のものよりも複雑です。 String
を解析することから始めます。次に、値が-128〜127の場合、対応するオブジェクトを静的キャッシュから返します。値がこの範囲外の場合、new Integer()
を呼び出して値を渡し、新しいオブジェクトを取得します。
ここで、質問の3つの式を検討してください。
_Integer.valueOf("127")==Integer.valueOf("127");
_
値が127のInteger
が静的キャッシュから2回取得され、それ自体と比較されるため、これはtrueを返します。含まれるInteger
オブジェクトは1つだけなので、true
を返します。
_Integer.valueOf("128")==Integer.valueOf("128");
_
128は静的キャッシュにないため、これはfalse
を返します。そのため、等式の両側に新しいInteger
が作成されます。 2つの異なるInteger
オブジェクトがあり、オブジェクトの_==
_は、両側がまったく同じオブジェクトである場合にのみtrue
を返すため、これはfalse
になります。
_Integer.parseInt("128")==Integer.valueOf("128");
_
これは、左側のプリミティブint
値128と、右側の新しく作成されたInteger
オブジェクトを比較しています。ただし、int
をInteger
と比較することは意味をなさないため、Javaは、実行前にInteger
を自動的にunboxします比較;したがって、int
をint
と比較することになります。プリミティブ128はそれ自体に等しいため、true
を返します。
これらのメソッドから値を返すように注意してください。 valueOfメソッドは整数インスタンスを返します:
public static Integer valueOf(int i)
parseIntメソッドは整数値(プリミティブ型)を返します。
public static int parseInt(String s) throws NumberFormatException
比較の説明:
メモリを節約するために、ラッパーオブジェクトの2つのインスタンスは、プリミティブ値が同じ場合は常に==になります。
- ブール
- バイト
- \ u0000から\ u007fまでの文字(7fは10進数で127)
- -128〜127の短整数
==を使用してプリミティブをラッパーと比較すると、ラッパーはアンラップされ、比較はプリミティブからプリミティブになります。
あなたの状況(上記のルールによる):
Integer.valueOf("127")==Integer.valueOf("127")
この式は、-128〜127の整数値を含むため、trueを返すため、同じオブジェクトへの参照を比較します。
Integer.valueOf("128")==Integer.valueOf("128")
この式は、異なるオブジェクトへの参照を比較します。これらのオブジェクトには<-128、127>にない整数値が含まれているため、falseが返されます。
Integer.parseInt("128")==Integer.valueOf("128")
この式は、プリミティブ値(左側)とオブジェクトへの参照(右側)を比較するため、右側はアンラップされ、プリミティブ型は左側と比較されるため、trueが返されます。
256の整数のうち-128〜127の間の整数オブジェクトキャッシュ
オブジェクト参照を==または!=と比較しないでください。代わりに.equals(..)を使用するか、より良い方法-整数ではなくプリミティブintを使用してください。
parseInt:文字列引数を符号付き10進整数として解析します。文字列の文字はすべて10進数でなければなりませんが、最初の文字は負の値を示すためにASCIIマイナス記号 '-'( '\ u002D')である場合があります。結果の整数値引数と基数10がparseInt(Java.lang.String、int)メソッドの引数として指定された場合とまったく同じように返されます。
valueOf 2番目の引数で指定された基数で解析された場合、指定されたStringから抽出された値を保持するIntegerオブジェクトを返します。最初の引数は、引数がparseInt(Java.lang.String、int)メソッドに渡された場合とまったく同じように、2番目の引数で指定された基数の符号付き整数を表すと解釈されます。結果は、文字列で指定された整数値を表すIntegerオブジェクトです。
に相当
_new Integer(Integer.parseInt(s, radix))
_
radix-sの解釈に使用される基数
そのため、その間の整数がInteger.valueOf()
に等しい場合
-128〜127は、条件でtrueを返します。
_lesser than
_ -128および_greater than
_ 127の場合、false
が得られます
指定された回答を補完するために、次の点にも注意してください。
public class Test {
public static void main(String... args) {
Integer a = new Integer(129);
Integer b = new Integer(129);
System.out.println(a == b);
}
}
このコードは以下も出力します:false
ユーザー Jay は受け入れられた回答のコメントを要求しているため、オブジェクトで演算子==
を使用する場合は注意が必要です。ここでは、両方の参照が同じかどうかを確認しています。 、これらはまったく同じ値を表しますが、異なるオブジェクトであるためです。オブジェクトを比較するには、代わりにequals
メソッドを使用する必要があります。
Integer a = new Integer(128);
Integer b = new Integer(128);
System.out.println(a.equals(b));
これは印刷されます:true
しかし、最初の行がtrue
?を印刷した理由を尋ねることができます。 Integer.valueOf
メソッドのソースコードを確認すると、次のことがわかります。
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
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);
}
ParamがIntegerCache.low
(デフォルトは-128)とIntegerCache.high
(実行時に最小値127で計算)の間の整数である場合、事前に割り当てられた(キャッシュされた)オブジェクトが返されます。したがって、127をパラメーターとして使用すると、同じキャッシュオブジェクトへの2つの参照が取得され、参照の比較でtrue
が取得されます。