我编写了一段在无限循环中运行的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
循环。但实际上它是一个无限循环并继续打印价值。
这里发生了什么?
答案 0 :(得分:188)
i <= j
被评估为true
,因为int会自动取消装箱
比较,然后i
和j
都保留默认值0
。
j <= i
被评估为true
。
i != j
评估为true
,因为i
和j
都是
不同的对象。在比较对象时,没有任何需要
自动拆箱。
所有条件都是正确的,并且您没有在循环中更改i
和j
,因此它无限运行。
答案 1 :(得分:40)
因为你正在比较
0 < = 0 (true) // unboxing
0 > = 0 (true) // unboxing
reference != secondReference (true)
因为您正在创建对象,而不是原始比较。因此它评估为 while(true) { // Never ending loop }
。
答案 2 :(得分:17)
答案 3 :(得分:1)
循环没有结束,因为你的条件是真的(i!= j是真的因为有2个不同的对象,而是使用Integer.valueOf)并且在循环内部值没有改变所以你的条件永远是真的。 / p>
答案 4 :(得分:1)
整数对象不同。它与基本的int类型不同。 所以你可以这样做。你做了什么只是比较对象,当然结果是真的。
答案 5 :(得分:1)
首先我们必须了解两种不同的情况,
案例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!=j
将是true
,因为它们都引用堆中的两个不同对象并且不能相同。但
在案例2中:i==j
将为true
,因为10都是整数文字而Java维护pool for Integer literals
,其值为(-128 <= X <= 127)
。因此,在这种情况下,10&lt; = 127结果为真,所以两者都将引用相同的对象。
答案 6 :(得分:0)
也许原因是'i'和'j'都是对象,对象比较与对象引用比较不同。请考虑使用!statesquals(j)而不是i!= j
答案 7 :(得分:0)
程序会继续显示i
的相同值,因为您没有递增或递减i
或j
的值。 for中的条件始终保持为true,因此它是一个无限循环。
答案 8 :(得分:0)
整数a =新整数(0); 整数b = new Integer(0);
&lt; =和&gt; =比较将使用未装箱的值0,而!=将比较参考并将成功,因为它们是不同的对象。
即便如此,我也会这样做,
整数a = 1000;整数b = 1000;
但这不是:
整数a = 100;整数b = 100;
原因是因为Integer在内部对-128和127之间的Integer对象使用缓存,并从该缓存中返回它所覆盖范围的实例。我不确定,但我想你也可以在包“java.lang.Integer.IntegerCache.high”中更改其最大值。
为了更好地理解,请检查网址:https://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching
答案 9 :(得分:-3)
你必须知道它在&amp;&amp;和这个和这个&amp;当你使用&amp;&amp;那么当第一个条件为真时,它检查第二个条件是否为假,然后它没有检查第三个条件,因为在&amp;运算符如果一个条件为false,则使用||时所有语句都为false然后,如果它看到真,那么它在你的代码中返回true,因为i和j等于第一个和第二个条件为真然后在第三个条件中它将是假的因为它们是相等的而条件是假的。