No tengo idea de por qué estas líneas de código devuelven valores diferentes:
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"));
El resultado es:
true
false
true
¿Por qué regresa el primero true
y el segundo false
? ¿Hay algo diferente que no sepa entre 127
y 128
? (Por supuesto que sé que 127
< 128
.)
Además, ¿por qué regresa el tercero true
?
He leído la respuesta a esta pregunta , pero aún no entendí cómo puede regresar true
y por qué regresa el código en la segunda línea false
.
java
integer
comparison
DnR
fuente
fuente
.equals()
, de lo contrario todas las apuestas están canceladas.Respuestas:
Hay una notable diferencia aquí.
valueOf
está devolviendo unInteger
objeto, que puede tener sus valores almacenados en caché entre -128 y 127. Es por eso que el primer valor regresatrue
- está almacenado en caché - y el segundo valor devuelvefalse
- 128 no es un valor almacenado en caché, por lo que está obteniendo dosInteger
instancias separadas .Es importante tener en cuenta que usted está comparando con referencias
Integer#valueOf
, y si usted está comparando un valor que es mayor de lo que los soportes de memoria caché, será no evaluar atrue
, incluso si los valores analizados son equivalentes (ejemplo de ello:Integer.valueOf(128) == Integer.valueOf(128)
). Usted debe utilizarequals()
en su lugar.parseInt
está devolviendo un primitivoint
. Es por eso que el tercer valor devuelvetrue
:128 == 128
se evalúa y, por supuesto, estrue
.Ahora, sucede un poco para lograr 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 tiene, a saber,
int
yInteger
. Obtendrá unaInteger
delvalueOf
lado derecho, por supuesto.Después de la conversión, estás comparando dos
int
valores primitivos . La comparación se realiza tal como cabría esperar con respecto a las primitivas, por lo que terminas comparando128
y128
.fuente
List
. El otro es un primitivo, que es solo un valor bruto.==
. de todos modos, está claro ahora.La
Integer
clase tiene un caché estático, que almacena 256Integer
objetos especiales , uno para cada valor entre -128 y 127. Con eso en mente, considere la diferencia entre estos tres.Esto (obviamente) hace un nuevo
Integer
objeto.Esto devuelve un
int
valor primitivo después de analizar elString
.Esto es más complejo que los demás. Comienza analizando el
String
. Luego, 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, invocanew Integer()
y pasa el valor, para que obtenga un nuevo objeto.Ahora, considere las tres expresiones en la pregunta.
Esto devuelve verdadero, porque
Integer
cuyo valor es 127 se recupera dos veces del caché estático y se compara con sí mismo. Solo hay unInteger
objeto involucrado, así que esto regresatrue
.Esto vuelve
false
, porque 128 no está en el caché estático. EntoncesInteger
se crea una nueva para cada lado de la igualdad. Dado que hay dosInteger
objetos diferentes , y==
para los objetos solo se devuelvetrue
si ambos lados son exactamente el mismo objeto, esto seráfalse
.Esto es comparar el
int
valor primitivo 128 a la izquierda, con unInteger
objeto recién creado a la derecha. Pero debido a que no tiene sentido comparar unint
anInteger
, un Java desempaquetará automáticamente elInteger
antes de hacer la comparación; entonces terminas comparando unaint
con unaint
. Como el primitivo 128 es igual a sí mismo, esto vuelvetrue
.fuente
Tenga cuidado de devolver los valores de estos métodos. El método valueOf devuelve una instancia de Integer:
El método parseInt devuelve un valor entero (tipo primitivo):
Explicación para la comparación:
En su situación (de acuerdo con las reglas anteriores):
Esta expresión compara referencias al mismo objeto porque contiene un valor entero entre -128 y 127, por lo que regresa
true
.Esta expresión compara referencias a diferentes objetos porque contienen valores enteros que no están en <-128, 127> por lo que devuelve
false
.Esta expresión compara el valor primitivo (lado izquierdo) y la referencia al objeto (lado derecho) para que el lado derecho se desenvuelva y su tipo primitivo se compare con el izquierdo para que regrese
true
.fuente
==
, porque son objetos diferentes.Los objetos enteros se almacenan en caché entre -128 y 127 de 256 enteros
No debe comparar referencias de objetos con == o ! = . Deberías usar . igual (..) en su lugar, o mejor - use el primitivo int en lugar de Integer.
parseInt : analiza el argumento de cadena como un entero decimal con signo. Todos los caracteres de la cadena deben ser dígitos decimales, excepto que el primer carácter puede ser un signo menos ASCII '-' ('\ u002D') para indicar un valor negativo. Se devuelve el valor entero resultante, exactamente como si el argumento y la raíz 10 fueran dados como argumentos al método parseInt (java.lang.String, int).
valueOf 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 se hubieran dado al método parseInt (java.lang.String, int). El resultado es un objeto entero que representa el valor entero especificado por la cadena.
equivalente a
radix: la raíz que se utilizará para interpretar s
así que si eres igual
Integer.valueOf()
para el número entero entre-128 a 127 vuelve verdadero en su condición
para
lesser than
-128 ygreater than
127 dafalse
fuente
Para complementar las respuestas dadas, también tenga en cuenta lo siguiente:
Este código también imprimirá:
false
Como el usuario Jay ha afirmado en un comentario para la respuesta aceptada, se debe tener cuidado al usar el operador
==
en los objetos, aquí está comprobando si ambas referencias son iguales, lo que no es así, porque son objetos diferentes, aunque representan el mismo mismo valor Para comparar objetos, debe usar elequals
método en su lugar:Esto imprimirá:
true
Usted puede preguntar, pero entonces ¿por qué se imprime la primera línea
true
? . Verificando el código fuente delInteger.valueOf
método, puede ver lo siguiente:Si el parámetro es un número entero entre
IntegerCache.low
(predeterminado en -128) yIntegerCache.high
(calculado en tiempo de ejecución con el valor mínimo 127), se devuelve un objeto preasignado (en caché). Entonces, cuando usa 127 como parámetro, obtiene dos referencias al mismo objeto en caché y obtienetrue
la comparación de las referencias.fuente