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!)

Foi útil?

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 ou long, então um teste de igualdade inteira é realizado; Se o tipo promovido for float orDouble`, 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

Perguntas relacionadas

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top