为什么(i <= j && j <= i && i!= j)的计算结果为TRUE?
我写了一段运行在无限循环中的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
,起初看起来程序不会进入while
循环。 但实际上这是一个无限循环,并不断打印价值。
这里发生了什么?
-
i <= j
被评估为true
,因为int比较发生自动拆箱,然后i
和j
保持默认值0
。 -
由于上述原因,
j <= i
被评估为true
。 -
i != j
被评估为true
,因为i
和j
是不同的对象。 在比较对象时,不需要自动拆箱。
所有的条件都是真的,你不会改变i
和j
的循环,所以它是无限的运行。
因为你在比较
-
0 < = 0 (true) // unboxing
-
0 > = 0 (true) // unboxing
-
reference != secondReference (true)
当你创build对象的时候,不是原始的比较。 所以它评估while(true) { // Never ending loop }
。
整数对象是不同的。 它与基本的inttypes不同。
看到这个答案: 如何正确比较Java中的两个整数?
i != j
部分是真实的,你所期望的是错误的。
循环没有结束,因为你的条件是真的(i!= j是真的,因为有2个不同的对象,使用Integer.valueOf)而在循环内的值不会改变,所以你的条件永远保持真实。
整数对象是不同的。 它与基本的inttypes不同。 所以你可以这样做。 你做什么只是比较对象,当然结果是真实的。
有两个不同的情况我们首先要了解,
情况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维护具有值(-128 <= X <= 127)
pool for Integer literals
。 所以,在这种情况下,10 <= 127的结果是真的,所以两者都会引用同一个对象。
也许原因是“i”和“j”都是对象,而对象比较与对象引用比较不一样。 请考虑使用!i.equals(j)而不是i!= j
该程序继续显示i
相同的值,因为你不增加或减lessi
或j
的值。 在for中的条件总是保持为true,所以它是一个无限循环。
整数a =新的整数(0); 整数b =新的整数(0);
<=和> =比较将使用取消装箱值0,而!=将比较参考,并将成功,因为它们是不同的对象。
即使这也会起作用,
整数a = 1000; 整数b = 1000;
但是这不是:
整数a = 100; 整数b = 100;
原因是因为Integer内部使用-128到127之间的Integer对象的caching,并从该caching返回它覆盖的范围的实例。 我不知道,但我想你也可以在包“java.lang.Integer.IntegerCache.high”中更改其最大值。
为了更好的理解检查url: https : //www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching
你必须知道它与&&有点不同,这和当你使用&&然后当第一个条件为真然后检查第二个条件,如果它的假然后它不检查第三个条件,因为在&运算符,如果一个条件是假的所有的如果使用||,语句是错误的 那么如果它看到true,那么它在你的代码中返回true,因为i和j是相等的第一和第二个条件是真的,那么在第三个条件中它将是假的,因为它们是相等的,而条件是假的。
- Java数组如何在开始时添加元素
- setUp / tearDown(@ Before / @ After)为什么我们在JUnit中需要它们?
- response.sendRedirect()和request.getRequestDispatcher()之间有什么区别?forward(request,response)
- 如何从android手机获取TimeZone?
- 如何避免Java中的构造器代码冗余?
- 以完全权限以pipe理员身份运行Java文件
- inheritance与构成的区别
- 什么可能是RejectedExecutionException的原因
- Spring 3expression式语言如何与属性占位符交互?