为什么(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比较发生自动拆箱,然后ij保持默认值0

  • 由于上述原因, j <= i被评估为true

  • i != j被评估为true ,因为ij是不同的对象。 在比较对象时,不需要自动拆箱。

所有的条件都是真的,你不会改变ij的循环,所以它是无限的运行。

因为你在比较

  • 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相同的值,因为你不增加或减lessij的值。 在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是相等的第一和第二个条件是真的,那么在第三个条件中它将是假的,因为它们是相等的,而条件是假的。