human
Pourquoi cela génère-t-il une ```NullPointerException```
```public static void main(String[] args) throws Exception {
    Boolean b = true ? returnsNull() : false; // NPE sur cette ligne.
    System.out.println(b);
}
public static Boolean returnsNull() {
    return null;
}
```
alors que cela ne le fait pas
```public static void main(String[] args) throws Exception {
    Boolean b = true ? null : false;
    System.out.println(b); // null
}
```
?
La solution consiste à remplacer ```false``` par ```Boolean.FALSE``` pour éviter que ```null``` ne soit déballé en ```boolean``` --ce qui n'est pas possible. Mais ce n'est pas la question. La question est pourquoi ? Y a-t-il des références dans la JLS qui confirment ce comportement, en particulier dans le deuxième cas
gpt
La différence réside dans le fait que le type explicite de la méthode ```returnsNull()``` affecte la typage statique des expressions lors de la compilation :
```E1: `true ? returnsNull() : false` - boolean (déballage automatique du deuxième opérande en boolean)
E2: `true ? null : false` - Boolean (autoboxing du troisième opérande en Boolean)
```
Voir la spécification du langage Java, section 15.25 Opérateur conditionnel ? :

* Pour E1, les types des deuxième et troisième opérandes sont respectivement ```Boolean``` et ```boolean```, donc cette clause s'applique :

  Si l'un des deuxième et troisième opérandes est de type boolean et que l'autre est de type Boolean, alors le type de l'expression conditionnelle est boolean.

Étant donné que le type de l'expression est ```boolean```, le deuxième opérande doit être coercé en ```boolean```. Le compilateur insère du code de déballage automatique pour le deuxième opérande (valeur de retour de ```returnsNull()```) afin de le rendre de type ```boolean```. Cela provoque bien sûr la NPE à partir du ```null``` retourné à l'exécution.
* Pour E2, les types des deuxième et troisième opérandes sont ```Boolean``` (et non ```Boolean``` comme dans E1 !) et ```boolean``` respectivement, donc aucune clause de typage spécifique ne s'applique (allez les lire !), donc la dernière clause "otherwise" s'applique :

  Sinon, les deuxième et troisième opérandes sont de types S1 et S2 respectivement. Soit T1 le type résultant de l'application de la conversion en boîte à S1, et soit T2 le type résultant de l'application de la conversion en boîte à S2. Le type de l'expression conditionnelle est le résultat de l'application de la conversion de capture (§5.1.10) à lub(T1, T2) (§15.12.2.7).


* S1 == ```Boolean``` (voir §4.1)
* S2 == ```boolean```
* T1 == box(S1) == ```Boolean``` (voir dernier élément de la liste des conversions en boîte dans §5.1.7)
* T2 == box(S2) == ```Boolean```
* lub(T1, T2) == ```Boolean```

Ainsi, le type de l'expression conditionnelle est ```Boolean``` et le troisième opérande doit être coercé en ```Boolean```. Le compilateur insère du code d'autoboxing pour le troisième opérande (```false```). Le deuxième opérande n'a pas besoin du déballage automatique comme dans ```E1```, donc pas de NPE de déballage automatique lorsque ```null``` est retourné.


Cette question nécessite une analyse de type similaire :
Type de résultat de l'opérateur conditionnel Java ?: