183

Java 1.5以降、多くの状況でIntegerほとんど交換できます。int

しかし、コードに潜在的な欠陥があり、少し驚いていました。

次のコード:

Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
    mismatch = true;

値が等しい場合、どのような状況であるかはわかりませんが、誤って設定の不一致が発生しているように見えました。Eclipseにブレークポイントを設定し、Integer値が両方とも137であることを確認し、ブール式を調べたところ、falseと表示されましたが、ステップオーバーすると、不一致がtrueに設定されていました。

条件を次のように変更します。

if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))

問題を修正しました。

なぜこれが起こったのか、誰かが光を当てることができますか?これまでのところ、自分のPC上のローカルホストでの動作のみを確認しました。この特定のケースでは、コードは約20回の比較を正常に通過しましたが、2回で失敗しました。問題は一貫して再現可能でした。

これが一般的な問題である場合は、他の環境(開発とテスト)でエラーが発生しているはずですが、これまでのところ、このコードスニペットを実行した何百ものテストの後で問題を報告した人は誰もいません。

2つの値==を比較するために使用することはまだ合法ではありませんか?Integer

以下のすべての細かい答えに加えて、次のstackoverflowリンクにはかなりの追加情報があります。実際には元の質問に答えていたはずですが、質問でオートボクシングについて言及しなかったため、選択した提案には表示されませんでした。

コンパイラ/JVMがオートボクシングを「正しく機能」させることができないのはなぜですか?

4

7 に答える 7

286

JVMは整数値をキャッシュしています。したがって、との比較は==、-128〜127の数値に対してのみ機能します。

参照:#Immutable_Objects_.2F_Wrapper_Class_Caching

于 2010-09-03T17:08:53.733 に答える
86

Integer2つを単純なオブジェクトと比較することはできない==ため、ほとんどの場合、参照は同じではありません。

-128から127の間のトリックがあり、参照は小さな整数をキャッシュIntegerするオートボクシングの使用と同じになります。Integer.valueOf()

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


資力 :

同じトピックについて:

于 2010-09-03T17:10:26.727 に答える
5

問題は、2つの整数オブジェクトがまさにそのオブジェクトであるということです。内の値ではなく、2つのオブジェクト参照を比較しているため、これらは一致しません。明らか.equalsに、オブジェクト参照の比較ではなく、値の比較を提供するためにオーバーライドされます。

于 2010-09-03T17:06:04.990 に答える
5

Integer参照を参照します。つまり、比較する参照が値ではなく同じオブジェクトを指している場合に参照します。したがって、あなたが見ている問題。プレーンタイプで非常にうまく機能する理由intは、に含まれる値のボックスを解除するためIntegerです。

あなたがしていることをしているのなら、なぜif最初に声明を出すのですか?

mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) );
于 2010-09-03T17:07:08.823 に答える
5

"=="は、常に値のメモリ位置またはオブジェクト参照を比較します。equalsメソッドは常に値を比較します。ただし、equalsは間接的に「==」演算子を使用して値を比較します。

Integerは、Integerキャッシュを使用して、-128〜+127の値を格納します。==演算子を使用して、-128〜127の値をチェックすると、trueが返されます。これらの値以外の場合はfalseを返します。

追加情報については、リンクを参照してください

于 2016-07-28T06:13:04.963 に答える
3

これらの与えられた素晴らしい答えに加えて、私が学んだことは次のとおりです。

参照によってオブジェクトを比較する場合を除いて、オブジェクトを==と比較しないでください。

于 2020-04-16T01:57:25.553 に答える
2

使用の正確さのために、次のように、比較を行う前に、比較された値==の1つをボックスから外すことができます。Integer==

if ( firstInteger.intValue() == secondInteger ) {..

2番目は自動的に箱から出されます(もちろん、null最初にsをチェックする必要があります)。

于 2020-05-13T09:20:45.297 に答える