Reputation: 574
So, I've seen this line of code:
Boolean variable = false;
/* ..stuff.. */
if(variable.booleanValue() == false) {
/* ..more stuff..*/
}
And I've done, in a different place:
Boolean variable = false;
/* ..my stuff..*/
if(!variable) {
/* ..more of my stuff..*/
}
The question is: What is the difference/advantages of the first snippet of code over the first?
The long version is: Given I can use the Boolean variable as a primitive (boolean) one, what's the point on doing variable.booleanValue() and even comparing it to a boolean value? Doesn't this also introduces the risk (on the code impossible, but hey) of a null pointer exception if variable is not initialised?
There's any case in which is advisable using variable.booleanValue above just "variable"?
Upvotes: 9
Views: 7828
Reputation: 49754
There is no difference between the behaviour of the two snippets.
At run time, unboxing conversion proceeds as follows:
If r is a reference of type Boolean, then unboxing conversion converts r into r.booleanValue()
So if (variable) {...}
will execute as if (variable.booleanValue()) {...}
. And because they're completely equivalent, they're both equally susceptible to NPE if variable == null
.
This means that a possible minor advantage of the explicit call to booleanValue()
is that you can instantly see that variable
is being dereferenced, while with variable == false
it is slightly less obvious.
Whether you add == false
or a negation is a matter of taste, I prefer to avoid using the ==
operator to compare a boolean expression to true
or false
.
But I think it's more important that you avoid Boolean
altogether and use the primitive type where possible.
Upvotes: 8
Reputation: 54649
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"
}
Upvotes: 3
Reputation: 425073
The difference is auto unboxing.
The first version, which is better coded as:
if (variable.booleanValue())
does not require auto unboxing, so can be used with pre 1.5 versions of Java.
The second version, uses auto unboxing, and so requires version 1.5 and above.
If you need your code to run on and old Java version, you must use version 1.
Both can throw NPE, so there's no difference on that point.
Upvotes: 4
Reputation: 4693
Boolean
has three states - true
, false
and null
. If you have in uninitialized then you will get NullPointerException
in case of writing !var
.
Also remember, objects are autoinitialized to null
while boolean primitive to false
.
Upvotes: 1
Reputation: 4870
I suppose that the only advantage of the first method over the second it´s the posibility to compile the code with older JDK's/ Java languaje specification prior to Java 1.5
Upvotes: 3