为什么(i <= j && j <= i && i!= j)评估为TRUE?

Ksh*_*ain 104 java

我编写了一段在无限循环中运行的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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,当看到while循环中的条件时,首先看起来该程序不会进入while循环内部.但实际上它是一个无限循环并保持打印价值.

这里发生了什么?

Jun*_*san 188

  • i <= j被评估true的,因为自动拆箱发生了INT比较,那么这两个ij保持默认值0.

  • j <= itrue由于上述原因而被评估.

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

所有的条件都为真,并没有更改i,并j在循环,所以它是无限运行.

  • @PunithRaj <&>运算符处理基元而不是对象,因此对这些运算符进行自动拆箱.但是==和!=运算符也可以用于对象比较,所以不需要在这里进行拆箱,因此比较了对象. (41认同)
  • 啊,隐含拳击/拆箱的隐患!! (14认同)
  • 你可以解释一下,为什么!=正在检查参考对象的内存索引而<=正在检查整数的非盒装值?为什么这些运算符之间存在这样的差异? (10认同)
  • 请注意,`Integer.valueOf(0)== Integer.valueOf(0)`总是被评估为true,因为在这种情况下会返回相同的对象(请参阅IntegerCache http://grepcode.com/file/repository.grepcode.com /java/root/jdk/openjdk/6-b14/java/lang/Integer.java#Integer.IntegerCache) (4认同)
  • Stack Overflow应该只添加一个新标签,"Auto-unboxing是Java中有史以来最大的错误".:-).除了Java Puzzler书籍的作者.用它来标记这些问题. (3认同)

Ash*_*ani 40

因为你在比较

  • 0 < = 0 (true) // unboxing

  • 0 > = 0 (true) // unboxing

  • reference != secondReference (true)在创建对象时,不是原始比较.所以它评估为while(true) { // Never ending loop }.

  • 喔!隐藏的自动UNBOXING龙......很好的解释. (2认同)

Col*_*nic 17

整数对象是不同的.它与基本的int类型不同.

看到这个答案:如何正确比较Java中的两个整数?

i != j部分是真的,你期望是假的.

  • @Kon:事实上这就是答案.由于自动装箱,条件#1和#2评估为"真".在#3的情况下,自动装箱不适用并且在对象(存储器位置)级别上进行比较. (6认同)