TL; DR
Java almacena en caché instancias enteras en caja desde -128
hasta 127
. Dado que está utilizando ==
para comparar referencias de objetos en lugar de valores , solo los objetos almacenados en caché coincidirán. long
Trabaje con valores primitivos sin caja o utilícelos .equals()
para comparar sus Long
objetos.
Versión larga (juego de palabras)
¿Por qué hay un problema al comparar la variable Long con un valor mayor que 127? Si el tipo de datos de la variable anterior es primitivo (largo), el código funciona para todos los valores.
Java almacena en caché instancias de objetos Integer del rango -128 a 127 . Dicho eso:
- Si establece en N variables largas el valor
127
(en caché ), todas las referencias señalarán la misma instancia de objeto. (N variables, 1 instancia)
- Si establece en N variables largas el valor
128
( no almacenado en caché ), tendrá una instancia de objeto apuntada por cada referencia. (N variables, N instancias)
Por eso es que esto:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
Produce esto:
verdadero
falso
Para el valor 127L , dado que ambas referencias (val1 y val2) apuntan a la misma instancia de objeto en la memoria (en caché), devuelve true
.
Por otro lado, para el valor 128 , dado que no hay una instancia almacenada en caché en la memoria, se crea una nueva para cualquier asignación nueva de valores en caja, lo que da como resultado dos instancias diferentes (señaladas por val3 y val4) y regresando false
en el comparación entre ellos.
Eso sucede únicamente porque está comparando dos Long
referencias de objeto , no long
valores primitivos, con el ==
operador. Si no fuera por este mecanismo de caché, estas comparaciones siempre fallarían, por lo que el verdadero problema aquí es comparar los valores en caja con el ==
operador.
Cambiar estas variables a long
tipos primitivos evitará que esto suceda, pero en caso de que necesite mantener su código usando Long
objetos, puede hacer estas comparaciones de manera segura con los siguientes enfoques:
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(Es necesaria una verificación nula adecuada, incluso para fundiciones)
En mi opinión , siempre es una buena idea seguir con los métodos .equals () cuando se trata de comparaciones de objetos.
Enlaces de referencia:
.longValue()
.