Encaixotado Primitives e Equivalência
-
19-09-2019 - |
Pergunta
Então me pediram esta pergunta hoje.
Integer a = 3;
Integer b = 2;
Integer c = 5;
Integer d = a + b;
System.out.println(c == d);
O que este programa imprimir? Ele retorna verdadeiro. Eu respondi que sempre irá imprimir falsa por causa de como eu entendi auto (e auto un) boxe. Eu estava sob a impressão de que a atribuição de um número inteiro = 3 vai criar uma nova Inteiro (3), de modo que um == irá avaliar a referência em vez do valor primitivo.
Alguém pode explicar isso?
Solução
Os valores in a box entre -128 a 127 são armazenados em cache. Boxe usa o método Integer.valueOf
, que usa o cache. Valores fora da faixa não são armazenados em cache e sempre criado como uma nova instância. Desde que seus valores estão dentro da faixa em cache, os valores são iguais usando == operador.
Citação da especificação da linguagem Java:
Se o valor p ser encaixotado é verdade, falsa, um byte, um char no intervalo \ U0000 para \ u007f, ou um int ou curto número entre -128 e 127, em seguida, deixar R1 e R2 ser os resultados de quaisquer dois conversões de boxe de p. É sempre o caso que R1 == r2.
http: // docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7
Outras dicas
Isto é o que está realmente acontecendo:
Integer c = Integer.valueOf(5);
Integer d = Integer.valueOf(a.intValue() + b.intValue());
Java mantém um cache de objetos Integer
entre -128 e 127. Compare com o seguinte:
Integer a = 300;
Integer b = 200;
Integer c = 500;
Integer d = a + b;
System.out.println(c == d);
Qual deve imprimir false
.
É porque alguns dos números inteiros (em caixa-auto) são armazenados em cache, então você está realmente comparando a mesma referência - este post tem exemplos mais detalhada e uma explicação.
Caching acontece fora de autoboxing também, considere o seguinte:
Integer a = 1;
Integer b = new Integer(1);
Integer c = Integer.valueOf(1);
System.out.println(a == b);
System.out.println(b == c);
System.out.println(c == a);
este será impresso:
false
false
true
Então eu acho que, geralmente, você quer ficar longe de '==' ao comparar objetos