java - relacionales - ¿Por qué el operador igual funciona para el valor entero hasta el número 128?
prioridad de operadores en java (7)
De acuerdo con las especificaciones del lenguaje Java:
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.
Consulte este artículo para obtener más información sobre el almacenamiento en memoria caché int
Esta pregunta ya tiene una respuesta aquí:
¿Por qué Integer "=" el operador no funciona para 128 y después de valores enteros? ¿Alguien puede explicar esta situación?
Este es mi entorno Java: versión de Java "1.6.0_37"
Java (TM) SE Runtime Environment (compilación 1.6.0_37-b06)
Java HotSpot (TM) 64-Bit Server VM (compilación 20.12-b01, modo mixto)
Código de muestra:
Integer a;
Integer b;
a = 129;
b = 129;
for (int i = 0; i < 200; i++) {
a = i;
b = i;
if (a != b) {
System.out.println("Value:"+ i + " - Different values");
} else {
System.out.println("Value"+ i + " Same values");
}
}
Parte de la salida de la consola:
Value:124 - Same values
Value:125 - Same values
Value:126 - Same values
Value:127 - Same values
Value:128 - Different values
Value:129 - Different values
Value:130 - Different values
Value:131 - Different values
Value:132 - Different values
¡Gracias!
Dependiendo de cómo obtenga sus instancias de Integer
, puede que no funcione para ningún valor:
System.out.println(new Integer(1) == new Integer(1));
huellas dactilares
false
Esto se debe a que el operador ==
aplicado a los operandos de tipo de referencia no tiene nada que ver con el valor que esos operandos representan.
El objeto Integer tiene un mecanismo de caché interno:
private static class IntegerCache {
static final int high;
static final Integer cache[];
static {
final int low = -128;
// high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer''s autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
También vea el método valueOf:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
Esta es la razón por la que debe usar valueOf
vez de un new Integer
. Autoboxing usa este caché.
También vea esta publicación: https://effective-java.com/2010/01/java-performance-tuning-with-maximizing-integer-valueofint/
Usar ==
no es una buena idea, use igual para comparar los valores.
Es porque la lógica de implementación de la clase Integer
. Ha preparado objetos para números hasta 128. Puede consultar http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Integer.java fuente de código abierto -jdk por ejemplo (buscar caché []).
Básicamente, los objetos no se deben comparar utilizando ==
en absoluto, con una excepción a Enums.
Mira el código fuente de Integer . Puede ver el almacenamiento en caché de valores allí.
El almacenamiento en caché solo ocurre si usa Integer.valueOf(int)
, no si usa un new Integer(int)
. El autoboxing utilizado por usted usa Integer.valueOf
De acuerdo con el JLS , siempre se puede contar con el hecho de que para valores entre -128 y 127, se obtienen los objetos enteros idénticos después del autoboxing, y en algunas implementaciones puede obtener objetos idénticos incluso para valores más altos.
En realidad, en Java 7 (y creo que en las versiones más nuevas de Java 6), la implementation de la clase IntegerCache ha cambiado, y el límite superior ya no está codificado, pero se puede configurar a través de la propiedad "java.lang.Integer.IntegerCache". alto ", así que si ejecuta su programa con el parámetro VM -Djava.lang.Integer.IntegerCache.high=1000
, obtendrá" Same values "para todos los valores.
Pero el JLS aún lo garantiza solo hasta 127:
Idealmente, encajonar un valor primitivo p dado, siempre arrojaría una referencia idéntica. En la práctica, esto puede no ser factible utilizando las técnicas de implementación existentes. Las reglas anteriores son un compromiso pragmático. La cláusula final anterior requiere que ciertos valores comunes siempre estén enmarcados en objetos indistinguibles. La implementación puede almacenarlos en caché, de forma perezosa o ansiosa.
Para otros valores, esta formulación no permite ninguna suposición sobre la identidad de los valores encuadrados por parte del programador. Esto permitiría (pero no requeriría) compartir algunas o todas estas referencias.
Esto garantiza que, en la mayoría de los casos, el comportamiento será el deseado, sin imponer una penalización de rendimiento excesiva, especialmente en dispositivos pequeños. Las implementaciones menos limitadas de memoria podrían, por ejemplo, almacenar en caché todos los caracteres y cortos, así como enteros y largos en el rango de -32K - + 32K.
Use .equals()
lugar de ==
.
Los valores enteros solo se almacenan en caché para números entre -127 y 128, porque se usan con más frecuencia.
if (a.equals(b)) { ... }
Integer
es una clase contenedora para int
.
Integer != Integer
compara la referencia real del objeto, donde int != int
comparará los valores.
Como ya se mencionó, los valores de -128 a 127 se almacenan en caché, por lo que se devuelven los mismos objetos para ellos.
Si está fuera de ese rango, se crearán objetos separados, por lo que la referencia será diferente.
Arreglarlo:
- Haz los tipos
int
o - Emitir los tipos a
int
o - Utilice
.equals()