105

無限ループで実行される Java コードを作成しました。

以下はコードです:

public class TestProgram {
    public static void main(String[] args){
        Integer i = new Integer(0);
        Integer j = new Integer(0);

        while(i<=j && j<=i && i!=j){
            System.out.println(i);
        }
    }
}

上記のコードで、whileループ内の状態を見ると、一見、そのプログラムはループに入っていないように見えwhileます。しかし、実際には無限ループであり、値を出力し続けます。

ここで何が起きてるの?

4

10 に答える 10

189
  • i <= jは に評価されますtrue。これは、自動アンボックス化が int 比較で発生し、両方がデフォルト値iを保持するためです。j0

  • j <= itrue以上の理由で に評価されます。

  • i != jとは異なるオブジェクトtrueであるため、は に評価されます。また、オブジェクトを比較している間、自動アンボックスの必要はありません。ij

すべての条件が真であり、変更ijループも行われていないため、無限に実行されています。

于 2013-09-14T17:46:26.397 に答える
41

比べてるから

  • 0 < = 0 (true) // unboxing

  • 0 > = 0 (true) // unboxing

  • reference != secondReference (true)プリミティブな比較ではなく、オブジェクトを作成しているためです。したがって、それは に評価されwhile(true) { // Never ending loop }ます。

于 2013-09-14T17:47:12.320 に答える
17

整数オブジェクトは異なります。基本の int 型とは異なります。

この回答を参照してください: Javaで2つの整数を適切に比較する方法は?

i != jあなたが間違っていると思っていた部分は本当です。

于 2013-09-14T17:45:19.253 に答える
2

最初に理解しなければならない 2 つの異なるケースがあります。

ケース 1:

        Integer i = new Integer(10);
        Integer j = new Integer(10);

        System.out.println((i<=j && j<=i && i!=j));
        System.out.println(i!=j);

ケース 2:

        Integer i = 10;
        Integer j = 10;

        System.out.println((i<=j && j<=i && i==j));
        System.out.println(i==j);

両者は異なるので、

ケース 1:両方i!=jtrueヒープ内の 2 つの異なるオブジェクトを参照しており、同じにすることはできないためです。しかし

ケース 2: 10 の両方が整数リテラルであり、Java が value を保持i==jしているためです。したがって、この場合、10<=127 の結果が true になるため、両方が同じオブジェクトを参照します。truepool for Integer literals(-128 <= X <= 127)

于 2014-02-23T19:20:59.130 に答える
1

おそらくその理由は、'i' と 'j' の両方がオブジェクトであり、オブジェクトの比較がオブジェクト参照の比較と同じではないためです。i!=j の代わりに !i.equals(j) の使用を検討してください

于 2013-09-14T17:47:00.553 に答える
1

整数 a = 新しい整数 (0); 整数 b = 新しい整数 (0);

<= と >= の比較ではボックス化されていない値 0 が使用されますが、!= では参照が比較され、それらは異なるオブジェクトであるため成功します。

これでも動作します i,e

整数 a = 1000; 整数 b = 1000;

しかし、これはしません:

整数 a = 100; 整数 b = 100;

その理由は、Integer が内部的に -128 から 127 までの Integer オブジェクトのキャッシュを使用し、カバーする範囲のそのキャッシュからインスタンスを返すためです。よくわかりませんが、パッケージ「java.lang.Integer.IntegerCache.high」で最大値を変更することもできると思います。

理解を深めるために、URL を確認してください: https://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching

于 2013-09-27T09:59:00.537 に答える
1

条件が true であるためループは終了しません ( i != j は true です。2 つの異なるオブジェクトがあるため、代わりに Integer.valueOf を使用します)。ループ内では値が変化しないため、条件は永久に true のままです。

于 2013-09-14T17:46:11.653 に答える
0

またはiの値をインクリメントまたはデクリメントしていないため、プログラムは の同じ値を表示し続けます。for の条件は常に true に評価され続けるため、無限ループです。ij

于 2013-09-15T02:19:43.277 に答える
-3

&& this と this & で少し異なることを知っておく必要があります && を使用すると、最初の条件が true の場合、2 番目の条件が false の場合はチェックされ、3 番目の条件はチェックされません。 || を使用する場合、ステートメントは false です。次に、 true が表示された場合、 i と j が等しいため、コードで true を返します。最初と 2 番目の条件が true であり、3 番目の条件では、それらが等しいため false になります。

于 2013-09-20T05:32:59.133 に答える