¿Cómo funcionan los operadores! = Y == en enteros en Java?

El siguiente código me pareció realmente confuso ya que proporcionaba dos salidas diferentes. El código fue probado en jdk 1.7.

public class NotEq { public static void main(String[] args) { ver1(); System.out.println(); ver2(); } public static void ver1() { Integer a = 128; Integer b = 128; if (a == b) { System.out.println("Equal Object"); } if (a != b) { System.out.println("Different objects"); } if (a.equals(b)) { System.out.println("Meaningfully equal."); } } public static void ver2() { Integer i1 = 127; Integer i2 = 127; if (i1 == i2) { System.out.println("Equal Object"); } if (i1 != i2){ System.out.println("Different objects"); } if (i1.equals(i2)){ System.out.println("Meaningfully equal"); } } } 

Salida:

[ver1 salida]
Diferentes objetos
Significativamente igual.

[ver2 salida]
Igual Objeto
Significativamente igual

¿Por qué la prueba == y! = Produce resultados diferentes para ver1 () y ver2 () para el mismo número mucho menos que el Integer.MAX_VALUE? ¿Se puede concluir que == verificar números mayores a 127 (para las clases contenedoras como Integer como se muestra en el código) es una pérdida de tiempo?

Los enteros se almacenan en caché para valores entre -128 y 127, por lo que el Integer i = 127 siempre devolverá la misma referencia. Integer j = 128 no necesariamente lo hará. Luego necesitará usar equals para probar la igualdad de la int subyacente.

Esto es parte de la Especificación del lenguaje Java :

Si el valor p que aparece en la casilla es verdadero, falso, un byte o un carácter en el rango de \ u0000 a \ u007f, o un número entero o corto entre -128 y 127 (inclusive), entonces r1 y r2 son el resultado de dos conversiones de boxeo de p. Siempre es el caso que r1 == r2.

Pero 2 llamadas a Integer j = 128 pueden devolver la misma referencia (no garantizada):

Las implementaciones menos limitadas de memoria podrían, por ejemplo, almacenar en caché todos los valores de char y cortos, así como los valores int y long en el rango de -32K a +32K.

Debido a que los enteros pequeños están internados en Java, y usted probó los números en diferentes lados del límite de “pequeñez”.

Existe un caché de objetos enteros desde -128 hasta 127 por defecto. El borde superior se puede configurar. El borde superior de la caché puede controlarse mediante la opción VM -XX:AutoBoxCacheMax=

Está utilizando este caché cuando usa el formulario:

  Integer i1 = 127; 

o

 Integer i1 = Integer.valueOf(127); 

Pero cuando usas

 Integer i1 = new Integer(127); 

entonces tienes la garantía de obtener un nuevo objeto que no esté en la memoria caché. En este último caso, ambas versiones imprimen los mismos resultados. Usando las versiones en caché pueden diferir.

https://www.owasp.org/index.php/Java_gotchas

Recibí este enlace de uno de mis profesores, bastante informativo.

Java almacena en caché enteros de -128 a 127 Es por eso que los objetos SON iguales.

Creo que los operadores == y! = Al tratar con primitivas funcionarán de la forma en que los está usando actualmente, pero con objetos (Integer vs. int) querrá realizar pruebas con el método .equals ().

No estoy seguro de esto, pero con objetos, el == probará si un objeto es el mismo objeto o no, mientras que .equals () realizará la prueba de que esos dos objetos contienen equivalencia en el valor (o el método tendrá que ser creado / redefinido) para objetos personalizados.