Pergunta

Possíveis duplicatas:
Booleanos, operadores condicionais e auto -espinheiro
Java, Google Collections Library; Problema com AbstractIterator?

O código abaixo produz um NPE:

Integer test = null;
Integer test2 = true ? test : 0;
System.out.println(test2);

Para imprimir corretamente "NULL" sem uma exceção requer este código:

Integer test = null;
Integer test2 = true ? test : (Integer)0;
System.out.println(test2);

É óbvio no primeiro exemplo de que "teste" está sendo não caixa (convertido em INT nativo), mas por quê? E por que alterar a outra expressão no operador ternário (como no segundo exemplo) a corrige? Alguém pode fornecer algum tipo de narrativa exatamente quando, o quê e por que as coisas em ambos os exemplos são encaixotadas e não caixas?

Foi útil?

Solução

A partir de Seção 15.25 da especificação de idiomas Java:

O tipo de expressão condicional é determinada da seguinte forma:

  • Se o segundo e o terceiro operando tiverem o mesmo tipo (que pode ser o tipo nulo), esse é o tipo de expressão condicional.
    • Se um dos segundo e terceiro operando for do tipo booleano e o tipo do outro é do tipo booleano, o tipo de expressão condicional é booleano.
    • Se um dos segundos e terceiros operandos for do tipo nulo e o tipo do outro é um tipo de referência, o tipo de expressão condicional é esse tipo de referência.
    • Caso contrário, se o segundo e o terceiro operando tiverem tipos que são conversíveis (§5.1.8) em tipos numéricos, existem vários casos:
      • Se um dos operandos for de tipo byte ou byte e o outro é do tipo curto ou curto, o tipo de expressão condicional será curto.
      • Se um dos operandos é do tipo T, onde T é byte, curto ou char, e o outro operando é uma expressão constante do tipo int cujo valor é representável no tipo T, o tipo de expressão condicional é t.
      • Se um dos operandos for do tipo byte e o outro operando é uma expressão constante do tipo int cujo valor é representável no tipo byte, o tipo de expressão condicional é byte.
      • Se um dos operandos for do tipo curto e o outro operando é uma expressão constante do tipo int cujo valor é representável no tipo curto, o tipo de expressão condicional é curto.
      • Se um dos operando for do tipo; O caractere e o outro operando é uma expressão constante do tipo int cujo valor é representável no tipo char, então o tipo de expressão condicional é char.
      • Caso contrário, a promoção numérica binária (§5.6.2) é aplicada aos tipos de operando, e o tipo de expressão condicional é o tipo promovido do segundo e terceiro operando. Observe que a promoção numérica binária executa conversão de unboxing (§5.1.8) e conversão de conjunto de valores (§5.1.13).

Por isso, está seguindo a bala final, realizando promoção numérica binária, que executa uma conversão de unboxing. Portanto, o tipo de expressão do operador condicional é int, mesmo que você esteja atribuindo a um Integer. Está tentando realizar a conversão de unboxing em null, daí a exceção.

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