É garantido que o novo número inteiro (i) == i em java?
-
26-09-2019 - |
Pergunta
Considere o seguinte snippet:
int i = 99999999;
byte b = 99;
short s = 9999;
Integer ii = Integer.valueOf(9); // should be within cache
System.out.println(new Integer(i) == i); // "true"
System.out.println(new Integer(b) == b); // "true"
System.out.println(new Integer(s) == s); // "true"
System.out.println(new Integer(ii) == ii); // "false"
É óbvio por que a última linha vai SEMPRE impressões "false"
: estamos usando ==
comparação de identidade de referência e um new
objeto Will NUNCA ser ==
para um objeto já existente.
A questão é sobre as três primeiras linhas: são essas comparações garantido estar no primitivo int
, com o Integer
UNBOXED automático? Existem casos em que a primitiva seria caixa automática e as comparações de identidade de referência são realizadas? (que tudo seria então false
!)
Solução
Sim. JLS §5.6.2 Especifica as regras para a promoção numérica binária. Em parte:
Quando um operador aplica promoção numérica binária a um par de operandos, cada um dos quais deve denotar um valor que seja conversível a um tipo numérico, as seguintes regras se aplicam, em ordem, usando a ampliação da conversão (§5.1.2) para converter operando conforme necessário :
Se algum dos operandos for do tipo de referência, a conversão de unboxing (§5.1.8) for realizada.
A promoção numérica binária se aplica a vários operadores numéricos, incluindo "os operadores de igualdade numérica == e! =".
JLS §15.21.1 (Operadores de igualdade numérica == e! =) Especifica:
Se os operandos de um operador de igualdade forem do tipo numérico, ou um é do tipo numérico e o outro for conversível (§5.1.8) em tipo numérico, a promoção numérica binária será realizada nos operandos (§5.6.2).
Em contraste, JLS §15.21.3 (Operadores de igualdade de referência == e! =) Fornece:
Se os operandos de um operador de igualdade são do tipo de referência ou do tipo nulo, a operação é igualdade de objeto
Isso se encaixa no entendimento comum do boxe e do desbotamento, isso é feito apenas quando há uma incompatibilidade.
Outras dicas
Vou explicar primeiro precisamente quando ==
é uma igualdade de referência, e precisamente quando É uma igualdade numérica. As condições para a igualdade de referência são mais simples, por isso serão explicadas primeiro.
JLS 15.21.3 Operadores de igualdade de referência ==
e !=
Se os operandos de um operador de igualdade são do tipo de referência ou do nulo Tipo, então a operação é igualdade de objeto.
Isso explica o seguinte:
System.out.println(new Integer(0) == new Integer(0)); // "false"
Ambos os operandos são Integer
, que são tipos de referência, e é por isso que o ==
é comparação de igualdade de referência e dois new
Objetos nunca serão ==
um para o outro, é por isso que imprime false
.
Por ==
ser igualdade numérica, pelo menos um do operando deve ser um tipo numérico; Isso é especificado da seguinte maneira:
JLS 15.21.1 Operadores de igualdade numérica ==
e !=
Se os operandos de um operador de igualdade forem Ambas do tipo numérico, ou um é do tipo numérico e o outro é conversível Para o tipo numérico, a promoção numérica binária é realizada nos operandos. Se o tipo promovido dos operandos for
int
oulong
, então um teste de igualdade inteira é realizado; Se o tipo promovido forfloat or
Double`, então um teste de igualdade de ponto flutuante é realizado.Observe que a promoção numérica binária executa a conversão do conjunto de valores e a conversão de unboxing.
Assim, considere o seguinte:
System.out.println(new Integer(0) == 0); // "true"
Isso impressa true
, Porque:
- o operando certo é um numérico
int
modelo - o operando esquerdo é conversível para um tipo numérico, unindo -se
int
- Portanto
==
é uma operação de igualdade numérica
Resumo
- Se ambos os operando de
==
e!=
são tipos de referência, sempre será uma operação de igualdade de referência- Não importa se os operando são conversíveis para tipos numéricos
- Se pelo menos um do operando for um tipo numérico, sempre será uma operação de igualdade numérica
- A unidade de unidade automática em um (no máximo!) Dos operandos será executado, se necessário
Referências
- JLS 4.2. Tipos e valores primitivos
- "O Tipos numéricos são os tipos integrais e os tipos de ponto flutuante. "
- Guia de idiomas Java/Autoboxing
- JLS 5.1.8 UNBOXING Conversão
- JLS 15.21.1 Operadores de igualdade numérica
==
e!=
- JLS 15.21.3 Operadores de igualdade de referência
==
e!=
- JLS 5.6.2 Promoção numérica binária