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 truey el segundo false? ¿Hay algo diferente que no sepa entre 127y 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 truey 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í.
valueOfestá devolviendo unIntegerobjeto, 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 dosIntegerinstancias 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.parseIntestá devolviendo un primitivoint. Es por eso que el tercer valor devuelvetrue:128 == 128se 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,
intyInteger. Obtendrá unaIntegerdelvalueOflado derecho, por supuesto.Después de la conversión, estás comparando dos
intvalores primitivos . La comparación se realiza tal como cabría esperar con respecto a las primitivas, por lo que terminas comparando128y128.fuente
List. El otro es un primitivo, que es solo un valor bruto.==. de todos modos, está claro ahora.La
Integerclase tiene un caché estático, que almacena 256Integerobjetos especiales , uno para cada valor entre -128 y 127. Con eso en mente, considere la diferencia entre estos tres.Esto (obviamente) hace un nuevo
Integerobjeto.Esto devuelve un
intvalor 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
Integercuyo valor es 127 se recupera dos veces del caché estático y se compara con sí mismo. Solo hay unIntegerobjeto involucrado, así que esto regresatrue.Esto vuelve
false, porque 128 no está en el caché estático. EntoncesIntegerse crea una nueva para cada lado de la igualdad. Dado que hay dosIntegerobjetos diferentes , y==para los objetos solo se devuelvetruesi ambos lados son exactamente el mismo objeto, esto seráfalse.Esto es comparar el
intvalor primitivo 128 a la izquierda, con unIntegerobjeto recién creado a la derecha. Pero debido a que no tiene sentido comparar unintanInteger, un Java desempaquetará automáticamente elIntegerantes de hacer la comparación; entonces terminas comparando unaintcon 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 than127 dafalsefuente
Para complementar las respuestas dadas, también tenga en cuenta lo siguiente:
Este código también imprimirá:
falseComo 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 elequalsmétodo en su lugar:Esto imprimirá:
trueUsted puede preguntar, pero entonces ¿por qué se imprime la primera línea
true? . Verificando el código fuente delInteger.valueOfmé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 obtienetruela comparación de las referencias.fuente