Les answer by Telcontar points sur la seule chose que je peux penser à techniquement faire une différence: Le deuxième extrait de code repose sur Autoboxing (or rather auto-unboxing), et donc, nécessite la version Java> = 1.5.
En dehors de cela, il n'y a pas de différence technique. Vous avez mentionné
Cela ne présente-t-il pas également le risque (sur le code impossible, mais bon) d'une exception de pointeur nul si la variable n'est pas initialisée?
mais c'est le cas pour les deux versions. Même le second va lancer un NullPointerException
lorsque la variable est null
.
Cependant, j'étais curieux de celui-ci aussi bien, et a fait un test:
public class TheManyShadesOfFasle
{
public static int testBoxedBooleanBooleanValueComparison()
{
Boolean variable = false;
if(variable.booleanValue() == false)
{
return 0;
}
return 1;
}
public static int testBoxedBooleanComparison()
{
Boolean variable = false;
if(variable == Boolean.FALSE)
{
return 0;
}
return 1;
}
public static int testBoxedBooleanBooleanValueDirect()
{
Boolean variable = false;
if(!variable.booleanValue())
{
return 0;
}
return 1;
}
public static int testBoxedBooleanDirect()
{
Boolean variable = false;
if(!variable)
{
return 0;
}
return 1;
}
public static int testBooleanComparison()
{
boolean variable = false;
if(variable == false)
{
return 0;
}
return 1;
}
public static int testBooleanDirect()
{
boolean variable = false;
if(!variable)
{
return 0;
}
return 1;
}
}
Cela peut être décompilé avec javap -c
, pour obtenir le bytecode:
public static int testBoxedBooleanBooleanValueComparison();
Code:
0: iconst_0
1: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4: astore_0
5: aload_0
6: invokevirtual #3 // Method java/lang/Boolean.booleanValue:()Z
9: ifne 14
12: iconst_0
13: ireturn
14: iconst_1
15: ireturn
public static int testBoxedBooleanComparison();
Code:
0: iconst_0
1: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4: astore_0
5: aload_0
6: getstatic #4 // Field java/lang/Boolean.FALSE:Ljava/lang/Boolean;
9: if_acmpne 14
12: iconst_0
13: ireturn
14: iconst_1
15: ireturn
public static int testBoxedBooleanBooleanValueDirect();
Code:
0: iconst_0
1: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4: astore_0
5: aload_0
6: invokevirtual #3 // Method java/lang/Boolean.booleanValue:()Z
9: ifne 14
12: iconst_0
13: ireturn
14: iconst_1
15: ireturn
public static int testBoxedBooleanDirect();
Code:
0: iconst_0
1: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4: astore_0
5: aload_0
6: invokevirtual #3 // Method java/lang/Boolean.booleanValue:()Z
9: ifne 14
12: iconst_0
13: ireturn
14: iconst_1
15: ireturn
public static int testBooleanComparison();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: ifne 8
6: iconst_0
7: ireturn
8: iconst_1
9: ireturn
public static int testBooleanDirect();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: ifne 8
6: iconst_0
7: ireturn
8: iconst_1
9: ireturn
Et on peut voir que le bytecode de testBoxedBooleanBooleanValueComparison
et testBoxedBooleanDirect
(correspondant à votre premier et deuxième extrait de code) sont identique. (Cela signifie essentiellement: L'auto-unboxing est implicitement appelant la méthode booleanValue
de Boolean
en interne). La même chose pour if(!variable.booleanValue())
, comme on peut le voir dans testBoxedBooleanBooleanValueDirect
.
Les autres cas sont principalement là pour l'exhaustivité: Les cas testBooleanComparison
et testBooleanDirect
ont chacun le même bytecode, mais il diffère des autres parce qu'il n'y a pas de déballage ou de derefencing ayant lieu.
Un cas intéressant de souligner: Une comparaison de la variable à Boolean.FALSE
ou Boolean.TRUE
peut donner un sens, car elle couvre implicitement le cas de la variable null
:
if (variable == Boolean.TRUE) {
...
} else {
// Here, the variable is either "false" or "null"
}
vs
if (variable == Boolean.FALSE) {
...
} else {
// Here, the variable is either "true" or "null"
}
Le risque de l'exception de pointeur nul est également présent dans le deuxième fragment - seulement masqué, donc on peut considérer qu'il vaut encore la peine. Mon goût est pour la seconde, cependant. Je n'aime pas comparer les valeurs booléennes avec '== true' ou' == false'. Et non, je ne peux pas penser à un exemple où je voudrais appeler 'booleanValue()' explicitement. –
Comme mentionné - vos états ici utilisent la boxe/unboxing. De manière réaliste, c'est la même chose que Boolean val = Boolean.FALSE (ou TRUE), qui peut être déconnecté à un état primitif de vrai/faux en utilisant le qui est le même que d'appeler le .booleanValue() sur l'objet - Big Boolean est utile si vous voulez dire à tout à fait dans les boutons radio de l'application web - Null, True/False il y en a beaucoup d'autres mais c'est le principal pour lequel nous l'utilisons. – VeenarM