Obtenir NullPointerException indésirable dans un opérateur ternaire – Pourquoi?

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 :

entrer la description de l'image ici

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é.