Necesidad de unboxing automático de if-else ternario

23

Este código funciona bien: -

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

Pero esto arroja una excepción de puntero nulo, mientras que Eclipse advierte que hay necesidad de unboxing automático:

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

¿Por qué es así? ¿Alguien puede guiar por favor?

91StarSky
fuente

Respuestas:

22

El tipo de la expresión condicional ternaria

1 <= 3 ? nullInt : -1

es int(el JLS contiene varias tablas que describen el tipo del operador condicional ternario dependiendo de los tipos de los operandos segundo y tercero).

Por lo tanto, cuando intenta desempaquetar nullInta an int, NullPointerExceptionse lanza a.

Para obtener el comportamiento de su fragmento if-else, debe escribir:

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

Ahora el tipo de la expresión será Integer, por lo que no se realizará unboxing.

Eran
fuente
44
Solo para agregar a su respuesta, aquí están las tablas mencionadas: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen
3

Estoy bastante seguro de que los argumentos para el operador ternario deben ser de este mismo tipo. Como usas -1 y algún nullintcompilador constante intenta desempaquetar nullintpara obtener valor. Y luego autobox para almacenar en secondNullvariable.

Los tosters
fuente
3

Esto se debe a que cuando los dos operandos para el operador condicional ? :son un tipo primitivo y su tipo de referencia en caja, se realiza una conversión de unboxing ( JLS §15.25.2 ):

El tipo de una expresión condicional numérica se determina de la siguiente manera:

  • ...
  • Si uno de los operandos segundo y tercero es de tipo primitivo T, y el tipo del otro es el resultado de aplicar la conversión de boxeo (§5.1.7) a T, entonces el tipo de expresión condicional es T.

En general, reemplazar una ifdeclaración con una ? :expresión no siempre conserva el significado del código, porque la ? :expresión en sí misma debe tener un tipo de tiempo de compilación. Eso significa que cuando los tipos de los dos operandos son diferentes, se debe realizar una conversión a uno o ambos para que el resultado tenga un tipo de tiempo de compilación consistente.

kaya3
fuente
2

Este funcionó (en Java 1.8):

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