Por qué hacer = = comparaciones con Integer.valueOf (Cadena) ¿da resultados diferentes para 127 y 128?
No tengo idea de por qué estas líneas de código devuelven diferentes valores:
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
La salida es:
true
false
true
¿por Qué la primera vuelta true
y el segundo retorno false
? ¿Hay algo diferente que no sepa entre 127
y 128
? (Por supuesto que sé que 127
128.)
También, ¿por qué el tercero regresa true
?
He leído la respuesta de esta pregunta , pero todavía no entiendo cómo puede regresar true
, y por qué el código en la segunda línea devuelve false
.
5 answers
Hay una diferencia sorprendente aquí.
valueOf
devuelve un objeto Integer
, que puede tener sus valores almacenados en caché entre -128 y 127. Esta es la razón por la que el primer valor devuelve true
- está almacenado en caché - y el segundo valor devuelve false
- 128 no es un valor almacenado en caché, por lo que obtendrá dos instancias Integer
separadas.
Es importante tener en cuenta que está comparando referencias con Integer#valueOf
, y si está comparando un valor que es más grande que lo que admite la caché, lo hará no evaluar a true
, incluso si los valores analizados son equivalentes (caso en punto: Integer.valueOf(128) == Integer.valueOf(128)
). Usted debe usar equals()
en su lugar.
parseInt
está devolviendo un primitivo int
. Esta es la razón por la que el tercer valor devuelve true
- 128 == 128
se evalúa, y es por supuesto, true
.
Ahora, un poco justo sucede para hacer ese tercer resultado true
:
Se produce una conversión de unboxing con respecto al operador de equivalencia que está utilizando y los tipos de datos que tener-a saber,
int
yInteger
. Usted está recibiendo unInteger
devalueOf
en el lado derecho, por supuesto.Después de la conversión, estás comparando dos valores primitivos
int
. La comparación ocurre tal y como esperarías con respecto a las primitivas, por lo que terminas comparando128
y128
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-02 22:49:55
La clase Integer
tiene una caché estática, que almacena 256 objetos Integer
especiales - uno por cada valor entre -128 y 127. Con eso en mente, considere la diferencia entre estos tres.
new Integer(123);
Esto (obviamente) hace un nuevo objeto Integer
.
Integer.parseInt("123");
Esto devuelve un valor primitivo int
después de analizar el String
.
Integer.valueOf("123");
Esto es más complejo que los otros. Comienza por analizar el String
. Entonces, si el valor está entre -128 y 127, devuelve el objeto correspondiente de la caché estática. Si el valor está fuera de este rango, entonces invoca new Integer()
y pasa el valor, para que obtenga un nuevo objeto.
Ahora, consideremos las tres expresiones de la pregunta.
Integer.valueOf("127")==Integer.valueOf("127");
Esto devuelve true, porque el Integer
cuyo valor es 127 se recupera dos veces de la caché estática, y se compara consigo mismo. Solo hay un objeto Integer
involucrado, por lo que devuelve true
.
Integer.valueOf("128")==Integer.valueOf("128");
Esto devuelve false
, porque 128 no es en la caché estática. Así se crea un nuevo Integer
para cada lado de la igualdad. Dado que hay dos objetos Integer
diferentes, y ==
for objects solo devuelve true
si ambos lados son exactamente el mismo objeto, esto va a ser false
.
Integer.parseInt("128")==Integer.valueOf("128");
Esto es comparar el valor primitivo int
128 a la izquierda, con un objeto recién creado Integer
a la derecha. Pero debido a que no tiene sentido comparar un int
con un Integer
, Java descomprimirá automáticamente el Integer
antes de hacer la comparación; así terminas comparando un int
un int
. Dado que el primitivo 128 es igual a sí mismo, esto devuelve true
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-02 06:32:25
Tenga cuidado de devolver los valores de estos métodos. El método valueOf devuelve la instancia entera:
public static Integer valueOf(int i)
El método parseInt devuelve un valor entero (tipo primitivo):
public static int parseInt(String s) throws NumberFormatException
Explicación para la comparación:
Con el fin de ahorrar memoria, dos instancias de la wrapper objects, will always be = = when their valores primitivos son los mismos:
- Booleano
- Byte
- Carácter de \u0000 a \u007f (7f es 127 en decimal)
- Corto y entero de -128 a 127
Cuando == se usa para comparar una primitiva con una envoltura, la envoltura será sin envolver y la comparación será primitiva a primitiva.
En su situación (de acuerdo con las reglas anteriores):
Integer.valueOf("127")==Integer.valueOf("127")
Esta expresión compara referencias al mismo objeto porque contiene un valor entero entre -128 y 127 por lo que devuelve true.
Integer.valueOf("128")==Integer.valueOf("128")
Esta expresión compara las referencias a diferentes objetos porque contienen valores enteros no en por lo que devuelve false.
Integer.parseInt("128")==Integer.valueOf("128")
Esta expresión compara el valor primitivo (lado izquierdo) y la referencia al objeto (lado derecho) así que el lado derecho se desenvolverá y su tipo primitivo se comparará con el izquierdo para que devuelva true.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-02 11:01:14
Para complementar las respuestas dadas, también tome nota de lo siguiente: {[13]]}
public class Test {
public static void main(String... args) {
Integer a = new Integer(129);
Integer b = new Integer(129);
System.out.println(a == b);
}
}
Este código también se imprimirá: false
Como el usuario Jay ha reclamado en un comentario la respuesta aceptada, hay que tener cuidado al usar el operador ==
en objetos, aquí estás comprobando si ambas referencias son iguales, que no lo es, porque son objetos diferentes, aunque representan el mismo valor. Para comparar objetos, debe usar el método equals
lugar:
Integer a = new Integer(128);
Integer b = new Integer(128);
System.out.println(a.equals(b));
Esto se imprimirá: true
Usted puede preguntar, Pero entonces ¿por qué la primera línea impresa true
?. Comprobando el código fuente para el método Integer.valueOf
, puede ver lo siguiente:
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
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);
}
Si el parámetro es un entero entre IntegerCache.low
(predeterminado a -128) y IntegerCache.high
(calculado en tiempo de ejecución con un valor mínimo 127), se devuelve un objeto preasignado (almacenado en caché). Así que cuando usas 127 como parámetro, obtienes dos referencias al mismo objeto almacenado en caché y obtienes true
en la comparación de las referencias.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:12
Objetos enteros cachés entre -128 y 127 de 256 Entero
No debe comparar referencias de objetos con == ¡o !=. Deberías usarlo .es igual a(..) en su lugar, o mejor - use el int primitivo en lugar de Entero.
ParseInt : Analiza el argumento string como un entero decimal con signo. Los caracteres de la cadena deben ser todos dígitos decimales, excepto que el primer carácter puede ser un signo menos ASCII ' - ' ('\u002D') para indicar un negativo valor. El valor entero resultante se devuelve, exactamente como si el argumento y la base 10 se dieran como argumentos al parseInt (java.lang.String, int) método.
Valor de Devuelve un objeto Entero que contiene el valor extraído de la cadena especificada cuando se analiza con la raíz dada por el segundo argumento. El primer argumento se interpreta como la representación de un entero con signo en la raíz especificada por el segundo argumento, exactamente como si los argumentos parseInt (java.lang.String, int) método. El resultado es un objeto Entero que representa el valor entero especificado por la cadena.
Equivalente a
new Integer(Integer.parseInt(s, radix))
Radix - la radix que debe utilizarse en la interpretación de s
Así que si es igual Integer.valueOf()
para el entero inbetween
-128 a 127 devuelve true en su condición
Para lesser than
-128 y greater than
127 da false
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-02 15:41:06