Não faço ideia por que essas linhas de código retornam 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"));
A saída é:
true
false
true
Por que o primeiro retorna true
e o segundo retorna false
? Existe algo diferente que eu não conheça 127
e 128
? (Claro que eu sei que 127
< 128
.)
Além disso, por que o terceiro retorna true
?
Eu li a resposta desta pergunta , mas ainda não entendi como ela pode retornar true
e por que o código na segunda linha retorna false
.
java
integer
comparison
DnR
fonte
fonte
.equals()
, caso contrário, todas as apostas estão desativadas.Respostas:
Há uma diferença marcante aqui.
valueOf
está retornando umInteger
objeto, que pode ter seus valores em cache entre -128 e 127. É por isso que o primeiro valor retornatrue
- ele é armazenado em cache - e o segundo valor retornafalse
- 128 não é um valor armazenado em cache, então você está recebendo duasInteger
instâncias separadas .É importante observar que você está comparando referências e
Integer#valueOf
, se estiver comparando um valor maior do que o cache suporta, ele não será avaliadotrue
, mesmo que os valores analisados sejam equivalentes (caso em questãoInteger.valueOf(128) == Integer.valueOf(128)
:). Você deve usar em seuequals()
lugar.parseInt
está retornando um primitivoint
. É por isso que o terceiro valor retornatrue
-128 == 128
é avaliado e, é clarotrue
,.Agora, acontece um pouco para obter esse terceiro resultado
true
:Uma conversão de unboxing ocorre com relação ao operador de equivalência que você está usando e os tipos de dados que você possui - ou seja,
int
eInteger
. Você está recebendo umInteger
dovalueOf
lado direito, é claro.Após a conversão, você está comparando dois
int
valores primitivos . A comparação acontece exatamente como seria de esperar em relação às primitivas, então você acaba comparando128
e128
.fonte
List
. O outro é um primitivo, que é apenas um valor bruto.==
. de qualquer maneira, está claro agora.A
Integer
classe possui um cache estático, que armazena 256Integer
objetos especiais - um para cada valor entre -128 e 127. Com isso em mente, considere a diferença entre esses três.Isso (obviamente) cria um novo
Integer
objeto.Isso retorna um
int
valor primitivo após analisar oString
.Isso é mais complexo que os outros. Começa analisando o arquivo
String
. Então, se o valor estiver entre -128 e 127, ele retornará o objeto correspondente do cache estático. Se o valor estiver fora desse intervalo, ele chamaránew Integer()
e passará o valor, para que você obtenha um novo objeto.Agora, considere as três expressões na pergunta.
Isso retorna true, porque o
Integer
valor cujo é 127 é recuperado duas vezes do cache estático e comparado a si mesmo. Há apenas umInteger
objeto envolvido, então isso retornatrue
.Isso retorna
false
, porque 128 não está no cache estático. Portanto, um novoInteger
é criado para cada lado da igualdade. Como existem doisInteger
objetos diferentes , e==
para os objetos retornará apenastrue
se os dois lados forem exatamente o mesmo objeto, será esse o casofalse
.Isso está comparando o
int
valor primitivo 128 à esquerda, com umInteger
objeto recém-criado à direita. Mas, como não faz sentido comparar umint
com umInteger
, o Java descompactará automaticamente oInteger
antes de fazer a comparação; então você acaba comparando umint
para umint
. Como o primitivo 128 é igual a si mesmo, isso retornatrue
.fonte
Cuide para retornar valores desses métodos. O método valueOf retorna uma instância Integer:
O método parseInt retorna um valor inteiro (tipo primitivo):
Explicação para comparação:
Na sua situação (de acordo com as regras acima):
Essa expressão compara referências ao mesmo objeto, pois contém o valor Inteiro entre -128 e 127 e, portanto, retorna
true
.Esta expressão compara referências a objetos diferentes porque eles contêm valores Inteiros que não estão em <-128, 127> e, portanto, retornam
false
.Essa expressão compara o valor primitivo (lado esquerdo) e a referência ao objeto (lado direito), para que o lado direito seja desembrulhado e seu tipo primitivo seja comparado ao esquerdo, para que ele retorne
true
.fonte
==
, porque são objetos diferentes.Objetos inteiros fazem cache entre -128 e 127 de 256 Inteiro
Você não deve comparar referências de objeto com == ou ! = . Você deveria usar . é igual a(..) vez disso, ou melhor - use o primitivo int em vez de Inteiro.
parseInt : analisa o argumento da string como um número inteiro decimal assinado. Os caracteres na sequência devem ser todos dígitos decimais, exceto que o primeiro caractere pode ser um sinal de menos ASCII '-' ('\ u002D') para indicar um valor negativo. O valor inteiro resultante é retornado, exatamente como se o argumento e a raiz 10 fossem fornecidos como argumentos para o método parseInt (java.lang.String, int).
valueOf Retorna um objeto Inteiro que mantém o valor extraído da String especificada quando analisado com a raiz fornecida pelo segundo argumento. O primeiro argumento é interpretado como representando um número inteiro assinado na raiz especificada pelo segundo argumento, exatamente como se os argumentos fossem fornecidos ao método parseInt (java.lang.String, int). O resultado é um objeto Inteiro que representa o valor inteiro especificado pela sequência.
equivalente a
radix - o radical a ser usado na interpretação de s
então se você igualar
Integer.valueOf()
para o número inteiro entre-128 a 127 retorna verdadeiro em sua condição
para
lesser than
-128 egreater than
127 dáfalse
fonte
Para complementar as respostas fornecidas, observe também o seguinte:
Este código também imprimirá:
false
Como o usuário Jay reivindicou em um comentário a resposta aceita, deve-se tomar cuidado ao usar o operador
==
em objetos, aqui você está verificando se as duas referências são iguais, o que não é, porque são objetos diferentes, embora representem o mesmo valor. Para comparar objetos, você deve usar oequals
método:Isso imprimirá:
true
Você pode perguntar: mas então por que a primeira linha foi impressa
true
? . Verificando o código fonte doInteger.valueOf
método, você pode ver o seguinte:Se o parâmetro for um número inteiro entre
IntegerCache.low
(padrão -128) eIntegerCache.high
(calculado em tempo de execução com valor mínimo 127), um objeto pré-alocado (em cache) será retornado. Portanto, quando você usa 127 como parâmetro, obtém duas referências ao mesmo objeto em cache e faztrue
a comparação das referências.fonte