The answer by Telcontar points out the only thing that I can think of to technically make a difference: The second code snippet relies on Autoboxing (or rather auto-unboxing), and thus, requires Java version >= 1.5.
Apart from that, there is no technical difference. You mentioned
Doesn't this also introduces the risk (on the code impossible, but hey) of a null pointer exception if variable is not initialized?
but this is the case for both versions. Even the second one will throw a NullPointerException
when the variable is null
.
However, I was curious about this one as well, and did a 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;
}
}
This can be decompiled with javap -c
, to obtain the bytecodes:
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
And one can see that the bytecode of testBoxedBooleanBooleanValueComparison
and testBoxedBooleanDirect
(corresponding to your first and second code snippet) are identical. (This basically means: The auto-unboxing is implicitly calling the booleanValue
method of Boolean
internally). The same for if(!variable.booleanValue())
, as it can be seen in testBoxedBooleanBooleanValueDirect
.
The other cases are mainly there for completeness: The testBooleanComparison
and testBooleanDirect
cases each have the same bytecode, but it differs from the other ones because there is no unboxing or derefencing taking place.
One case may be worth pointing out: A comparison of the variable to Boolean.FALSE
or Boolean.TRUE
can make sense, because it implicitly covers the case of the variable being 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"
}
== true
or== false
. And no, I can’t think of an example where I’d want to callbooleanValue()
explicitly. – Sonorant