ti-enxame.com

Java: Integer é igual a vs. ==

A partir de Java 1.5, você pode praticamente trocar Integer com int em muitas situações.

No entanto, encontrei um defeito potencial no meu código que me surpreendeu um pouco.

O código a seguir:

Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
    mismatch = true;

parecia estar incorretamente configurando incompatibilidade quando os valores eram iguais, embora eu não possa determinar sob quais circunstâncias. Eu configurei um ponto de interrupção no Eclipse e vi que os valores Integer eram ambos 137, e eu inspecionei a expressão booleana e ela disse que era falsa, mas quando eu pisei sobre ela, estava definindo incompatibilidade como true.

Alterando o condicional para:

if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))

corrigido o problema.

Alguém pode esclarecer por que isso aconteceu? Até agora, só vi o comportamento no meu host local no meu próprio PC. Neste caso particular, o código passou com sucesso por cerca de 20 comparações, mas falhou em 2. O problema foi consistentemente reproduzível.

Se for um problema prevalente, isso deve estar causando erros em nossos outros ambientes (dev e test), mas até agora, ninguém relatou o problema após centenas de testes que executam esse trecho de código.

Ainda não é legítimo usar == para comparar dois valores Integer?

Além de todas as respostas bem abaixo, o seguinte link stackoverflow tem um pouco de informação adicional. Na verdade, teria respondido à minha pergunta original, mas como não mencionei a caixa automática na minha pergunta, ela não apareceu nas sugestões selecionadas:

Por que o compilador/JVM não pode fazer o autoboxing "apenas funcionar"?

134
Jeremy Goodell

A JVM está armazenando valores inteiros em cache. == funciona apenas para números entre -128 e 127 http://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching

213
Adam

Você não pode comparar dois Integer com um simples == são objetos, então a maior parte das vezes as referências não serão as mesmas.

Existe um truque, com Integer entre -128 e 127, as referências serão as mesmas que a autoboxing usa Integer.valueOf() que armazena números inteiros pequenos.

Se o valor p sendo encaixotado for verdadeiro, falso, um byte, um caractere no intervalo\u0000 a\u007f ou um int ou um número curto entre -128 e 127, então seja r1 e r2 os resultados de quaisquer duas conversões de boxe p. É sempre o caso que r1 == r2.


Recursos:

No mesmo tópico:

69
Colin Hebert

A questão é que seus dois objetos Integer são apenas isso, objetos. Eles não correspondem porque você está comparando suas referências de dois objetos, não os valores internos. Obviamente .equals é substituído para fornecer uma comparação de valor em oposição a uma comparação de referência de objeto.

5
MattC

Integer refere-se à referência, isto é, ao comparar as referências que você está comparando se elas apontam para o mesmo objeto, não valor. Daí a questão que você está vendo. O motivo pelo qual ele funciona tão bem com os tipos int simples é que ele libera o valor contido no Integer.

Posso acrescentar que, se você está fazendo o que está fazendo, por que ter a instrução if para começar?

mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) );
4
wheaties

"==" sempre compare a localização da memória ou referências de objeto dos valores. O método Equals sempre compara os valores. Mas igual também indiretamente usa o operador "==" para comparar os valores.

Inteiro usa cache Integer para armazenar os valores de -128 a +127. Se o operador == for usado para verificar quaisquer valores entre -128 a 127, ele retornará verdadeiro. para outros que não esses valores, retorna false.

Indique o link para alguma informação adicional

3
vijay