verificar descargar java

java - descargar - ¿Por qué 128== 128 devuelve falso pero 127== 127 devuelve verdadero al convertir a envoltorios de enteros?



java offline (6)

class D { public static void main(String args[]) { Integer b2=128; Integer b3=128; System.out.println(b2==b3); } }

Salida:

false

class D { public static void main(String args[]) { Integer b2=127; Integer b3=127; System.out.println(b2==b3); } }

Salida:

true

Nota: los números entre -128 y 127 son verdaderos.


Autoboxing cachés -128 a 127. Esto se especifica en el JLS ( 5.1.7 ).

Si el valor p que está siendo encasillado es verdadero, falso, un byte, un carácter entre el rango / u0000 a / u007f, o un número entero o corto entre -128 y 127, entonces r1 y r2 serán los resultados de dos conversiones de boxeo de p. Siempre es el caso que r1 == r2.

Una regla simple para recordar cuando se trata de objetos es - use .equals si quiere verificar si los dos objetos son "iguales", use == cuando quiera ver si apuntan a la misma instancia.


Cuando compila un número literal en Java y lo asigna a un Entero (capital I ), el compilador emite:

Integer b2 =Integer.valueOf(127)

Esta línea de código también se genera cuando usa el autoboxing.

valueOf se implementa de forma que ciertos números se "agrupen", y devuelve la misma instancia para valores menores que 128.

Desde el código fuente de Java 1.6, línea 621:

public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i); }

El valor de high se puede configurar a otro valor, con la propiedad del sistema.

-Djava.lang.Integer.IntegerCache.high = 999

Si ejecuta su programa con esa propiedad del sistema, ¡dará como resultado verdadero!

La conclusión obvia: nunca confíe en que dos referencias sean idénticas, siempre compárelas con el método .equals() .

Entonces b2.equals(b3) se imprimirá verdadero para todos los valores lógicamente iguales de b2, b3.

Tenga en cuenta que la caché de enteros no está allí por motivos de rendimiento, sino que se ajusta al 5.1.7 ; la identidad del objeto debe darse para los valores -128 a 127 inclusive.

Integer#valueOf(int) también documenta este comportamiento:

es probable que este método produzca un mejor rendimiento de espacio y tiempo almacenando en caché valores solicitados con frecuencia. Este método siempre almacenará en caché los valores en el rango -128 a 127, inclusive, y puede almacenar en caché otros valores fuera de este rango.


Eche un vistazo al Integer.java, si el valor está entre -128 y 127, usará el grupo en caché, entonces (Integer) 1 == (Integer) 1 mientras (Integer) 222 != (Integer) 222

/** * Returns an {@code Integer} instance representing the specified * {@code int} value. If a new {@code Integer} instance is not * required, this method should generally be used in preference to * the constructor {@link #Integer(int)}, as this method is likely * to yield significantly better space and time performance by * caching frequently requested values. * * This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range. * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }


El uso de tipos de datos primitivos, ints, produciría verdadero en ambos casos, el resultado esperado.

Sin embargo, dado que está utilizando objetos enteros, el operador == tiene un significado diferente.

En el contexto de los objetos, == verifica si las variables se refieren a la misma referencia de objeto.

Para comparar el valor de los objetos, debe usar el método equals ().

b2.equals(b1)

que indicará si b2 es menor que b1, mayor que o igual a (consulte la API para obtener más detalles)


Es la optimización de la memoria en Java relacionada.

Para guardar en la memoria, Java "reutiliza" todos los objetos del contenedor cuyos valores se encuentran en los siguientes rangos:

Todos los valores booleanos (verdadero y falso)

Todos los valores de Byte

Todos los valores de caracteres desde / u0000 hasta / u007f (es decir, de 0 a 127 en decimal)

Todos los valores cortos e enteros de -128 a 127.

Nota:

  • si crea Boolean con nuevo Boolean (valor); siempre obtendrás un objeto nuevo

  • si creas Cadena con una nueva Cadena (valor); siempre obtendrás un objeto nuevo

  • si creas Entero con nuevo Entero (valor); siempre obtendrás un objeto nuevo

etc.


Escribí lo siguiente ya que este problema no es solo específico de Integer. Mi conclusión es que, en la mayoría de los casos, si utiliza la API incorrectamente, verá un comportamiento incorrecto. Úselo correctamente y debería ver el comportamiento correcto:

public static void main (String[] args) { Byte b1=127; Byte b2=127; Short s1=127; //incorrect should use Byte Short s2=127; //incorrect should use Byte Short s3=128; Short s4=128; Integer i1=127; //incorrect should use Byte Integer i2=127; //incorrect should use Byte Integer i3=128; Integer i4=128; Integer i5=32767; //incorrect should use Short Integer i6=32767; //incorrect should use Short Long l1=127L; //incorrect should use Byte Long l2=127L; //incorrect should use Byte Long l3=13267L; //incorrect should use Short Long l4=32767L; //incorrect should use Short Long l5=2147483647L; //incorrect should use Integer Long l6=2147483647L; //incorrect should use Integer Long l7=2147483648L; Long l8=2147483648L; System.out.print(b1==b2); //true (incorrect) Used API correctly System.out.print(s1==s2); //true (incorrect) Used API incorrectly System.out.print(i1==i2); //true (incorrect) Used API incorrectly System.out.print(l1==l2); //true (incorrect) Used API incorrectly System.out.print(s3==s4); //false (correct) Used API correctly System.out.print(i3==i4); //false (correct) Used API correctly System.out.print(i5==i6); //false (correct) Used API correctly System.out.print(l3==l4); //false (correct) Used API correctly System.out.print(l7==l8); //false (correct) Used API correctly System.out.print(l5==l6); //false (correct) Used API incorrectly }