3

Java(JDK 1.7)でこれに出くわしました:

    Integer a = 100;
    Integer b = 100;
    Integer c = 1000;
    Integer d = 1000;

    System.out.println(a == b); //true
    System.out.println(c == d); //false
    System.out.println(new Integer(100) == new Integer(100)); //false
    System.out.println(new Integer(1000) == new Integer(1000)); //false

出力は次のとおりです。 true false false false

a==b が true と評価されるのはなぜですか? これの理由は何ですか?これは文字列の内部化に似ていますか?

4

3 に答える 3

6

これは文字列の内部化に似ていますか?

はい - 基本的に、1 バイトに収まるすべての整数 (-128 から +127) はインターンされ、同じ基になるオブジェクトを共有します。より大きな整数はそうではないため、おそらく同じ基礎となるオブジェクトを共有しません (これは JLS 5.1.7 でカバーされています)。その方法で VM を実装します。

この範囲の「小さい」整数は、大きい整数よりもはるかに頻繁に使用されるため、潜在的なメモリフットプリントを削減するには、同じ基本オブジェクトを使用する価値があるという理論的根拠があると思います。

あなたの例では、 false と評価さnew Integer(100) == new Integer(100)れる方法と同様に、新しい整数オブジェクトを明示的に作成しているため、これは当てはまりません。new String("hi") == new String("hi")

繰り返しますが、すべての実世界のシナリオでこのような整数を比較する場合.equals()は、使用する必要があります (または、オブジェクト型を使用する適切なケースがない限り、プリミティブ整数で == を使用することをお勧めします)。

于 2013-09-17T13:17:10.813 に答える
1

これは、すべての小さな整数が (文字列の内部化のように) キャッシュされるためです。したがって、ボックス化すると同じインスタンスが得られます。

仕様から:

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

そして、追加のメモは、行われた妥協について啓発しています。

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

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

于 2013-09-17T13:17:03.207 に答える
1

-128 から 127 までの値がキャッシュされます

java.lang.Integer-128 から 127 までのすべての Integer オブジェクトをキャッシュする内部静的クラスがあります。

于 2013-09-17T13:18:04.783 に答える