Necessidade de descompactação automática de ternário if-else

23

Este trecho de código funciona bem: -

    Integer nullInt = null;
    if (1 <= 3) {
        Integer secondNull = nullInt;
    } else {
        Integer secondNull = -1;
    }
    System.out.println("done");

Mas isso gera uma exceção de ponteiro nulo, enquanto o Eclipse avisa que há necessidade de descompactação automática: -

    Integer nullInt = null;
    Integer secondNull = 1 <= 3 ? nullInt : -1;
    System.out.println("done");

Por que é assim, alguém pode guiar por favor?

91StarSky
fonte

Respostas:

22

O tipo da expressão condicional ternária

1 <= 3 ? nullInt : -1

é int(o JLS contém várias tabelas que descrevem o tipo do operador condicional ternário, dependendo dos tipos do segundo e do terceiro operandos).

Portanto, quando tenta desmarcar nullInta caixa para int, a NullPointerExceptioné lançada.

Para obter o comportamento do seu trecho if-else, você precisa escrever:

1 <= 3 ? nullInt : Integer.valueOf(-1)

Agora o tipo da expressão será Integer, portanto, nenhuma remoção da caixa de seleção ocorrerá.

Eran
fonte
4
Apenas para adicionar sua resposta, aqui estão as tabelas mencionadas: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen
3

Tenho certeza de que os argumentos para o operador ternário precisam ser desse mesmo tipo. Desde que você use -1 e algum nullintcompilador constante tenta desmarcar nullintpara obter valor. E depois autobox para armazenar na secondNullvariável.

The Tosters
fonte
3

Isso ocorre quando os dois operandos do operador condicional ? :são um tipo primitivo e seu tipo de referência em caixa, uma conversão de unboxing é feita ( JLS §15.25.2 ):

O tipo de uma expressão condicional numérica é determinado da seguinte maneira:

  • ...
  • Se um dos segundo e terceiro operandos for do tipo primitivo T, e o tipo do outro for o resultado da aplicação da conversão de boxe (§5.1.7) em T, o tipo da expressão condicional será T.

Em geral, substituir uma ifinstrução por uma ? :expressão nem sempre preserva o significado do código, porque a ? :própria expressão precisa ter um tipo de tempo de compilação. Isso significa que quando os tipos dos dois operandos são diferentes, uma conversão deve ser feita em um ou ambos, para que o resultado tenha um tipo consistente em tempo de compilação.

kaya3
fonte
2

Este funcionou (em Java 1.8):

Integer secondNull = 1 <= 3 ? null : -1;
Catalina Chircu
fonte