Benefits or uses for the Boolean.booleanValue function on Java?
Asked Answered
S

5

9

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"?

Sandpit answered 13/4, 2016 at 9:47 Comment(2)
The risk of the null pointer exception is in the second snippet as well — only disguised, so one might consider it still worth. My taste is for the second, though. I thoroughly dislike comparing boolean values with == true or == false. And no, I can’t think of an example where I’d want to call booleanValue() explicitly.Sonorant
As mentioned - your states here are using boxing/unboxing. Realistically its the same as Boolean val = Boolean.FALSE (or TRUE), which can be unboxed to a primitive state of true/false using the which is the same as calling the .booleanValue() on the Object - Big Boolean is useful if you want to state at all ie in web app radio buttons - Null, True/False there are many others but thats the main one we use it for.Tubate
M
8

There is no difference between the behaviour of the two snippets.

JLS 5.1.8:

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.

Monotheism answered 13/4, 2016 at 9:54 Comment(2)
+ 1 as it mentioned the fact unboxing / boxing is being used to derive the Object Boolean from primitive state.Tubate
Thanks! I did not know that the booleanValue was autocalled (hence, I did not got what was the point of the function at all, as I thought it was some kind of low-level java magic). I try to avoid this kind of wrappers, but you know, inherited code I can't touch.Sandpit
M
4

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.

Motoring answered 13/4, 2016 at 10:1 Comment(0)
N
3

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

Nonferrous answered 13/4, 2016 at 9:54 Comment(0)
T
3

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"
}
Thiourea answered 13/4, 2016 at 10:19 Comment(0)
G
1

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.

Gaultheria answered 13/4, 2016 at 9:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.