En exécutant le code suivant, je reçois un NullPointerException
à la ligne:
value = condition ? getDouble() : 1.0;
Dans les lignes précédentes, lorsque j'utilise null
au lieu de getDouble()
, tout fonctionne et c'est étrange.
public class Test {
static Double getDouble() {
return null;
}
public static void main(String[] args) {
boolean condition = true;
Double value;
value = condition ? null : 1.0; //works fine
System.out.println(value); //prints null
value = condition ? getDouble() : 1.0; //throws NPE
System.out.println(value);
}
}
Est-ce que quelqu'un peut m'aider à comprendre ce comportement?
Quand tu écris
value = condition ? null : 1.0;
le type de condition ? null : 1.0
doit être un type de référence; le type est donc Double
, qui peut contenir la valeur null
.
Quand tu écris
value = condition ? getDouble() : 1.0;
et getDouble()
renvoie null
, cela équivaut à écrire:
value = condition ? ((Double) null) : 1.0;
Dans ce cas, le compilateur considère que Double
et double
sont les deuxième et troisième arguments de l'opérateur conditionnel ternaire et décide que le type de l'expression doit être double
. Par conséquent, il décompresse le null
en double
, obtenant ainsi NullPointerException
.
Le type de l'opérateur ternaire conditionnel est déterminé par certaines tables de JLS 15.25 .
Si les deuxième et troisième opérandes sont null
et double
, le type d'expression conditionnelle est la limite supérieure inférieure de Double
et null
, qui est Double
.
Si les deuxième et troisième opérandes sont Double
et double
, le type d'expression conditionnelle est double
.
Voir # jls-15.25 :
Si le deuxième opérande est Double
alors que le troisième opérande est double
, le résultat:
getCount() == 1 ? getDouble() : 1.0
sera un double
.
Et lorsque vous essayez de convertir un Double null
(Renvoyé par getDouble()
) en double
, NPE
sera levé.