Lo primero a tener en cuenta es que los operadores ternarios de Java tienen un "tipo", y que esto es lo que el compilador determinará y considerará sin importar cuáles sean los tipos reales / reales del segundo o tercer parámetro. Dependiendo de varios factores, el tipo de operador ternario se determina de diferentes maneras, como se ilustra en la Especificación del lenguaje Java 15.26
En la pregunta anterior deberíamos considerar el último caso:
De lo contrario, el segundo y tercer operandos son de los tipos S1 y S2 respectivamente. Deje que T1 sea el tipo que resulta de aplicar la conversión de boxeo a S1 , y que T2 sea el tipo que resulta de aplicar la conversión de boxeo a S2 . El tipo de expresión condicional es el resultado de aplicar la conversión de captura (§5.1.10) a lub (T1, T2) (§15.12.2.7).
Este es, con mucho, el caso más complejo una vez que echa un vistazo a la aplicación de la conversión de captura (§5.1.10) y, sobre todo, en lub (T1, T2) .
En inglés simple y después de una simplificación extrema, podemos describir el proceso como el cálculo de la "Superclase menos común" (sí, piense en el MCM) del segundo y tercer parámetro. Esto nos dará el operador "tipo" ternario. Nuevamente, lo que acabo de decir es una simplificación extrema (considere las clases que implementan múltiples interfaces comunes).
Por ejemplo, si intenta lo siguiente:
long millis = System.currentTimeMillis();
return(true ? new java.sql.Timestamp(millis) : new java.sql.Time(millis));
Notarás que el tipo resultante de la expresión condicional se debe a java.util.Date
que es la "Superclase menos común" para el Timestamp
/ Time
par.
Dado que null
se puede autoboxear a cualquier cosa, la "Superclase menos común" es la Integer
clase y este será el tipo de retorno de la expresión condicional (operador ternario) anterior. El valor de retorno será entonces un puntero nulo de tipo Integer
y eso es lo que devolverá el operador ternario.
En tiempo de ejecución, cuando la máquina virtual de Java unboxes la Integer
una NullPointerException
se lanza. Esto sucede porque la JVM intenta invocar la función null.intValue()
, donde null
es el resultado del autoboxing.
En mi opinión (y dado que mi opinión no está en la Especificación del lenguaje Java, muchas personas lo encontrarán mal de todos modos) el compilador hace un mal trabajo al evaluar la expresión en su pregunta. Dado que usted escribió, true ? param1 : param2
el compilador debe determinar de inmediato que null
se devolverá el primer parámetro - y generará un error de compilación. Esto es algo similar a cuando escribe while(true){} etc...
y el compilador se queja del código debajo del bucle y lo marca Unreachable Statements
.
Su segundo caso es bastante sencillo y esta respuesta ya es demasiado larga ...;)
CORRECCIÓN:
Después de otro análisis, creo que me equivoqué al decir que un null
valor se puede encuadrar / encuadrar automáticamente en cualquier cosa. Hablando de la clase Integer, el boxeo explícito consiste en invocar al new Integer(...)
constructor o tal vez el Integer.valueOf(int i);
(encontré esta versión en alguna parte). El primero arrojaría un NumberFormatException
(y esto no sucede) mientras que el segundo simplemente no tendría sentido ya que un int
no puede ser null
...
int foo = (true ? null : 0)
ynew Integer(null)
ambos compilan bien, el segundo es la forma explícita de autoboxing.