He escrito un fragmento de código Java que se ejecuta en un bucle infinito.
A continuación se muestra el código:
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);
        }
    }
}
En el código anterior, mientras ve la condición en el whileciclo, al principio parece que ese programa no entrará en el whileciclo. Pero en realidad es un ciclo infinito y sigue imprimiendo el valor.
¿Que está sucediendo aquí?

i<=j && j<=i && i!=jesta condición siempre se evalúa como verdadera. Solo toma un pedazo de papel y evalúa que lo atraparás :)ioj, ¿cuándo esperaría que terminara el ciclo?i<=jyj<=ise puede concluir, esoi == j, que contradice el último término. Por lo tanto, toda la expresión se evalúa como falsa y no se ingresaría el while. ¡El punto clave es la identidad del objeto aquí!Respuestas:
i <= jse evalúatrue, porque el unboxing automático ocurre para las comparaciones int y luego tantoiyjmantenga el valor predeterminado,0.j <= ies evaluado paratruedebido a la razón anterior.i != jse evalúa atrue, porque tantoiyjson objetos diferentes. Y al comparar objetos, no es necesario un desempaquetado automático.Todas las condiciones son verdaderas y no está cambiando
inijen bucle, por lo que se ejecuta infinitamente.fuente
Integer.valueOf(0) == Integer.valueOf(0)siempre se evalúa como verdadero porque en este caso se devuelve el mismo objeto (consulte IntegerCache grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/… )Porque estas comparando
0 < = 0 (true) // unboxing0 > = 0 (true) // unboxingreference != secondReference (true)mientras crea objetos, no una comparación primitiva. Entonces evalúa awhile(true) { // Never ending loop }.fuente
Los objetos enteros son diferentes. Es diferente del tipo int básico.
Vea esta respuesta: ¿Cómo comparar correctamente dos enteros en Java?
La
i != jparte es verdadera, que esperabas que fuera falsa.fuente
truedebido al autoboxing. En el caso del # 3, el autoboxing no se aplica y la comparación se realiza a nivel de objeto (ubicación de memoria).El ciclo no termina porque su condición es verdadera (i! = J es verdadera porque hay 2 objetos diferentes, use Integer.valueOf en su lugar) y dentro del ciclo los valores no cambian, por lo que su condición permanece verdadera para siempre.
fuente
Los objetos enteros son diferentes. Es diferente del tipo int básico. para que puedas hacer eso. lo que haces es simplemente comparar el objeto y, por supuesto, el resultado es verdadero.
fuente
Hay dos casos diferentes que tenemos que entender primero,
caso 1:
caso 2:
ambos son diferentes, como
en el caso 1:
i!=jserátrueporque ambos hacen referencia a dos objetos diferentes en el montón y no pueden ser iguales. Peroen el caso 2:
i==jserátrueporque ambos 10 son literales enteros y Java mantienepool for Integer literalscuál tiene valor(-128 <= X <= 127). Entonces, en este caso 10 <= 127 resulta verdadero, por lo que ambos tendrán referencia al mismo objeto.fuente
Quizás la razón es que tanto 'i' como 'j' son objetos, y la comparación de objetos no es lo mismo que la comparación de referencias de objetos. Considere usar! I.equals (j) en lugar de i! = J
fuente
El programa sigue mostrando el mismo valor de
iporque no está incrementando ni disminuyendo el valor deioj. La condición en for siempre sigue evaluándose como verdadera, por lo que es un bucle infinito.fuente
i!=jparte que sorprendentemente se evalúa como verdadera y no las<=comparaciones.Las comparaciones <= y> = usarán el valor 0 sin caja, mientras que! = Comparará las referencias y tendrá éxito ya que son objetos diferentes.
Incluso esto también funciona i, e
pero esto no:
La razón es que Integer utiliza internamente el almacenamiento en caché para objetos Integer entre -128 y 127 y devuelve instancias de esa caché para el rango que cubre. No estoy seguro, pero supongo que también puede cambiar su valor máximo en el paquete "java.lang.Integer.IntegerCache.high".
Para una mejor comprensión, consulte la URL: https://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching
fuente
debe saber que es un poco diferente en && this y this & cuando usa && luego, cuando la primera condición es verdadera, entonces verifica la segunda condición si es falsa, entonces no verificó la tercera condición porque en el operador & si una condición es falsa todos los declaración es falsa si usa || luego, si ve verdadero, devuelve verdadero en su código porque i y j son iguales, la primera y la segunda condición son verdaderas, luego en la tercera condición será falsa porque son iguales y la condición while es falsa.
fuente