Besoin de déballage automatique du ternaire if-else

23

Ce morceau de code fonctionne bien: -

    Integer nullInt = null;
    if (1 <= 3) {
        Integer secondNull = nullInt;
    } else {
        Integer secondNull = -1;
    }
    System.out.println("done");

Mais cela lève une exception de pointeur nul, tandis qu'Eclipse avertit qu'il est nécessaire de décompresser automatiquement: -

    Integer nullInt = null;
    Integer secondNull = 1 <= 3 ? nullInt : -1;
    System.out.println("done");

Pourquoi en est-il ainsi, quelqu'un peut-il guider s'il vous plaît?

91StarSky
la source

Réponses:

22

Le type de l'expression conditionnelle ternaire

1 <= 3 ? nullInt : -1

is int(le JLS contient plusieurs tableaux qui décrivent le type de l'opérateur conditionnel ternaire en fonction des types des 2e et 3e opérandes).

Par conséquent, lorsqu'il essaie de décompresser nullIntvers un int, un NullPointerExceptionest lancé.

Pour obtenir le comportement de votre extrait if-else, vous devez écrire:

1 <= 3 ? nullInt : Integer.valueOf(-1)

Maintenant, le type de l'expression sera Integer, donc aucun déballage n'aura lieu.

Eran
la source
4
Juste pour ajouter à votre réponse, voici les tableaux mentionnés: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Parmi
3

Je suis à peu près sûr que les arguments de l'opérateur ternaire doivent être du même type. Puisque vous utilisez -1 et un nullintcompilateur constant, essayez nullintde décompresser pour obtenir de la valeur. Et puis le mettre en boîte automatique pour le stocker dans une secondNullvariable.

The Tosters
la source
3

En effet, lorsque les deux opérandes de l'opérateur conditionnel ? :sont de type primitif et son type de référence encadré, une conversion de décodage est effectuée ( JLS §15.25.2 ):

Le type d'une expression conditionnelle numérique est déterminé comme suit:

  • ...
  • Si l'un des deuxième et troisième opérandes est de type primitif T, et que le type de l'autre est le résultat de l'application de la conversion de boxe (§5.1.7) à T, alors le type de l'expression conditionnelle est T.

En général, le remplacement d'une ifinstruction par une ? :expression ne préserve pas toujours la signification du code, car l' ? :expression elle-même doit avoir un type au moment de la compilation. Cela signifie que lorsque les types des deux opérandes sont différents, une conversion doit être effectuée en un ou les deux afin que le résultat ait un type de compilation cohérent.

kaya3
la source
2

Celui-ci a fonctionné (en Java 1.8):

Integer secondNull = 1 <= 3 ? null : -1;
Catalina Chircu
la source