26

私と一緒に歩いて..

Integer x = 23;
Integer y = 23;

if (x == y)
    System.out.println("what else");      // All is well as expected
else
    System.out.println("...");

その間

Integer x = someObject.getIndex();
Integer y = someOtherObject.getSomeOtherIndex();

if (x == y)
    System.out.println("what else");  
else
    System.out.println("...");        // Prints this 

うーん... intにキャストしてみる

int x = someObject.getIndex();
int y = someOtherObject.getSomeOtherIndex()

if (x == y)       
    System.out.println("what else");   // works fine
else
    System.out.println("...");  

どちらも整数ですか?

System.out.println(x.getClass().getName());              // java.lang.Integer
System.out.println(y.getClass().getName());              // java.lang.Integer
System.out.println(someObject.getIndex());               // java.lang.Integer
System.out.println(someOtherObject.getSomeOtherIndex()); // java.lang.Integer

皆さんはどう思いますか?このようなことを説明するものは何ですか?

4

3 に答える 3

45

Integer参照である値を比較しています。オートボクシングを介してこれらの参照を考え出しています。一部の値 (-128 ~ 127 で保証) では、JRE はIntegerオブジェクトのキャッシュを維持します。より高い値の場合、そうではありません。JLS のセクション 5.1.7から:

ボックス化された値 p が true、false、\u0000 ~ \u007f の範囲のバイト、または char、または -128 ~ 127 (両端を含む) の int または short の数値である場合、r1 および r2 を次の結果とします。 p の任意の 2 つのボクシング変換。r1 == r2 は常にそうです。

理想的には、指定されたプリミティブ値 p をボックス化すると、常に同一の参照が生成されます。実際には、これは既存の実装技術を使用して実現できない場合があります。上記のルールは実用的な妥協案です。上記の最後の節では、特定の共通値を常に区別できないオブジェクトにボックス化する必要があります。実装は、遅延または積極的にこれらをキャッシュする場合があります。他の値については、この定式化により、プログラマー側でボックス化された値の同一性に関する仮定ができなくなります。これにより、これらの参照の一部またはすべてを共有できます (必要ではありません)。

これにより、ほとんどの一般的なケースで、特に小さなデバイスで過度のパフォーマンスのペナルティを課すことなく、動作が目的の動作になることが保証されます。メモリ制限の少ない実装では、たとえば、すべての char 値と short 値、および -32K から +32K の範囲の int 値と long 値をキャッシュする場合があります。

Integer道徳:根底にある価値観に興味がある場合は、参考文献を比較しないでくださいint。最初に値を使用.equals()または取得しintます。

于 2012-04-03T22:00:40.073 に答える
13

整数を正しく比較するには.equals()、プリミティブ値をキャストintまたは呼び出して使用または比較する必要がありintValue()ます。

Usingは、2 つの Integer が同じ数値を含むかどうかではなく、同じ Object==であるかどうかをチェックします。

    Integer a = new Integer(1);
    Integer b = new Integer(1);

    System.out.println(a.equals(b));                  //true
    System.out.println((int)a == (int)b);             //true
    System.out.println(a.intValue() == b.intValue()); //true
    System.out.println(a == b);                       //false

オートボクシングに関するJLSからのJonのポイントを説明するために編集されました:

    Integer a = 1;
    Integer b = 1;
    System.out.println(a.equals(b));                  //true
    System.out.println((int)a == (int)b);             //true
    System.out.println(a.intValue() == b.intValue()); //true
    System.out.println(a == b);                       //true

対:

    Integer a = 128;
    Integer b = 128;
    System.out.println(a.equals(b));                  //true
    System.out.println((int)a == (int)b);             //true
    System.out.println(a.intValue() == b.intValue()); //true
    System.out.println(a == b);                       //false
于 2012-04-03T22:02:09.367 に答える
1

==2 つの整数で使用すると、オートボクシングで何かがおかしくなっているように聞こえます。

Integerメソッドを使用すると、使用時に問題なく動作すると思いますequals()か?とにかく、それは私の推測によるとでしょう。

あなたはJava 1.4を使用していませんか?

于 2012-04-03T22:02:02.787 に答える