En exécutant le code suivant, je reçois une NullPointerException
à la ligne:
value = condition ? getDouble() : 1.0;
Dans les lignes précédentes, lorsque j’utilisais null
au lieu de getDouble()
tout fonctionne et c’est étrange.
public class Test { static Double getDouble() { return null; } public static void main(Ssortingng[] 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
condition ? null : 1.0
doit être un type de référence, donc le type est Double
, ce 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 un Double
et un double
comme les 2ème et 3ème arguments de l’opérateur conditionnel ternaire et décide que ce type d’expression doit être double
. Par conséquent, il désencapsule le null
pour obtenir une NullPointerException
.
Le type de l’opérateur ternaire conditionnel est déterminé par certaines tables dans JLS 15.25 .
Si les deuxièmes et troisièmes opérandes sont null
et double
, le type d’expression conditionnelle est la plus petite limite supérieure de Double
et la valeur 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 2ème opérande est Double
, alors que le 3è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()
) pour double
, NPE
sera lancé.