为什么(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循环中。但实际上它是一个无限循环,并且不断地输出值。

这里发生了什么?

8074 次浏览

The integer objects are different. It is different from the basic int type.

See this answer: How to properly compare two Integers in Java?

The i != j part is true, which you were expecting to be false.

The loop is not ending because your condition is true( i != j is true because there are 2 different objects, use Integer.valueOf instead) and inside the loop the values are not changing so your condition remains true forever.

  • i <= j is evaluated to true, because auto unboxing happens for int comparisons and then both i and j hold the default value, 0.

  • j <= i is evaluated to true because of the above reason.

  • i != j is evaluated to true, because both i and j are different objects. And while comparing objects, there isn't any need of auto unboxing.

All the conditions are true, and you are not changing i and j in loop, so it is running infinitely.

Perhaps the reason is that both 'i' and 'j' are objects, and object comparison is not the same as object reference comparison. Please consider using !i.equals(j) instead of i!=j

Because you are comparing

  • 0 < = 0 (true) // unboxing

  • 0 > = 0 (true) // unboxing

  • reference != secondReference (true) as you are creating objects, not a primitive comparison. So it evaluates to while(true) { // Never ending loop }.

The program keeps on displaying the same value of i because you aren't incrementing or decrementing either the value of i or j. The condition in the for always keeps evaluating to true, so it is an infinite loop.

you have to know its a bit different in && this and this & when you use && then when first condition is true then it check second condition if its false then it not checked third condition because in & operator if one condition is false all of the statement is false if use || then if it see true then it return true in your code because i and j is equal first and second condition are true then in third condition it will be false because they are equal and while condition is false .

The integer objects are different. It is different from the basic int type. so you can just do like that. what you do it's just compare the object and of course the result is true.

Integer a = new Integer(0); Integer b = new Integer(0);

The <= and >= comparisons will use the unboxed value 0, while the != will compare the references and will succeed since they are different objects.

Even this will also works i,e

Integer a = 1000; Integer b = 1000;

but this doesnot :

Integer a = 100; Integer b = 100;

The reason is because Integer internally uses caching for Integer objects between -128 and 127 and return instances from that cache for the range it covers. I am not sure but I guess you can also change its maximum value in package "java.lang.Integer.IntegerCache.high".

For better understanding check url : https://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching

There are two different cases which we have to understand first,

case 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);

case 2:

        Integer i = 10;
Integer j = 10;


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

both are different, as

in case 1: i!=j will be true because both referencing to two different object in heap and can't be same. But

in case 2: i==j will be true because both 10 are integer literals and Java maintains pool for Integer literals which have value (-128 <= X <= 127). So, in this case 10<=127 results true, So both will have reference to same object.