165

Java boolean allows values of true and false while Boolean allows true, false, and null. I have started to convert my booleans to Booleans. This can cause crashes in tests such as

Boolean set = null;
...
if (set) ...

while the test

if (set != null && set) ...

seems contrived and error-prone.

When, if ever, is it useful to use Booleans with null values? If never, then what are the main advantages of the wrapped object?

UPDATE: There has been such a lot of valuable answers that I have summarised some of it in my own answer. I am at best an intermediate in Java so I have tried to show the things that I find useful. Note that the question is "incorrectly phrased" (Boolean cannot "have a null value") but I have left it in case others have the same misconception

peter.murray.rust
  • 37,407
  • 44
  • 153
  • 217
  • 8
    Sometimes, you want an uninitialized state, and setting `Boolean` variable to `null` helps. – nhahtdh Jun 25 '12 at 07:50
  • And so you always have to test for null, correct? – peter.murray.rust Jun 25 '12 at 07:51
  • 3
    "Always" is a bit strong that I don't dare to confirm, but I would expect a test for `null` if it really is used as a 3rd state. – nhahtdh Jun 25 '12 at 07:54
  • see @Tomasz for equating null to false – peter.murray.rust Jun 25 '12 at 07:58
  • 6
    Do you have a reason to convert booleans to Booleans? I'd stick to the primitive type and wrap it only if there is a good reason to do so, e.g. when I need to pass a variable by reference. – jpe Jun 25 '12 at 07:58
  • @jpe not in the general case. I have used ikt in collections and when using reflection (as mentioned below). I thought it might be a GOOD THING but I wanted to be sure so that's why I asked! Now I am sure it's not – peter.murray.rust Jun 25 '12 at 08:07
  • Tony Hoare (inventor of quick sort and more) — “… null references were an expensive mistake. …”. see: http://mattcallanan.blogspot.co.uk/2010/09/tony-hoare-billion-dollar-mistake.html – ctrl-alt-delor Jun 25 '12 at 09:58
  • 7
    You also might want to check out this: http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx – biziclop Jun 25 '12 at 10:26
  • biziclop -- I saw the question and immediately thought of this. – Chris Cudmore Jun 25 '12 at 16:58
  • 6
    There's no such thing as a "null value *in* a Boolean". A `Boolean` is an object, while a `boolean` is a "scalar". If a `Boolean` reference is set to null that means that the corresponding `Boolean` object doesn't exist. You can't place anything inside something that doesn't exist. – Hot Licks Jun 25 '12 at 18:28
  • What about lazy evaluation? if(myBool == null){ myBool = expensiveCalculation(); } return myBool; – Fabio Marcolini Feb 14 '14 at 16:06
  • @biziclop: the best part of that wtf he doesn't even mention is that `Bool.True` evaluates to `false`, and `Bool.False` evaluates to `true`. – Tasgall Apr 13 '16 at 04:48

14 Answers14

254

Use boolean rather than Boolean every time you can. This will avoid many NullPointerExceptions and make your code more robust.

Boolean is useful, for example

  • to store booleans in a collection (List, Map, etc.)
  • to represent a nullable boolean (coming from a nullable boolean column in a database, for example). The null value might mean "we don't know if it's true or false" in this context.
  • each time a method needs an Object as argument, and you need to pass a boolean value. For example, when using reflection or methods like MessageFormat.format().
Tiny
  • 27,221
  • 105
  • 339
  • 599
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 36
    A null value in the database could also mean ["FileNotFound"](http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx) – Karl Johan Jun 25 '12 at 12:17
  • 37
    Your second bullet is really the core of the right answer to this question, I think. – Niels Brinch Jun 25 '12 at 15:07
  • 3
    Another use for Boolean that I've had is as a generic type parameter when extending generic classes - closely related to point 3. – Alex Jun 25 '12 at 16:17
  • 6
    Overloading the concept of null with a meaning other than "the universe doesn't know" it weaker than using a 3 (or more) valued enum. Makes reading code passing parameters into method more explicit, too. – bluevector Jun 26 '12 at 19:08
  • 1
    Even if you'll use a primitive boolean, NPE could happen when casting from Boolean. You probably use a lot of third-party code, which for sure contains a lot of Booleans. – unorsk Jun 27 '12 at 08:24
  • 1
    @JBNizet, that's what I say - using boolean will not "avoid NullPointerExceptions", but it will make your ride less risky – unorsk Jun 27 '12 at 09:07
  • 1
    @AndrewDashin: Ah, OK. I see what you meant now. I've edited my answer to make it clearer that it won't avoid all NPEs. – JB Nizet Jun 27 '12 at 09:16
  • 17
    Or #4: `Boolean isSchrodinger‎CatAlive = null;` (sorry, couldn't resist ;)). – Matthieu Dec 13 '13 at 23:02
  • 2
    @jonnyGold: The best thing about using a 3-valued enum is that you get a forth state (null) for free. ;) – maaartinus Feb 11 '14 at 10:56
59

I almost never use Boolean because its semantics are vague and obscure. Basically you have 3-state logic: true, false or unknown. Sometimes it is useful to use it when e.g. you gave user a choice between two values and the user didn't answer at all and you really want to know that information (think: NULLable database column).

I see no reason to convert from boolean to Boolean as it introduces extra memory overhead, NPE possibility and less typing. Typically I use awkward BooleanUtils.isTrue() to make my life a little bit easier with Boolean.

The only reason for the existence of Boolean is the ability to have collections of Boolean type (generics do not allow boolean, as well as all other primitives).

Magnilex
  • 11,584
  • 9
  • 62
  • 84
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 1
    It's an external library (Apache commons), though. – nhahtdh Jun 25 '12 at 07:59
  • 4
    For multivalued logic it is preferable to use enums. Thus Boolean should be left for (auto)boxing variables for use in data structures. – jpe Jun 25 '12 at 08:03
  • 41
    When using Boolean, a convenient test to avoid null pointer exceptions is [`Boolean.TRUE.equals(myBooleanObject)`](http://docs.oracle.com/javase/6/docs/api/java/lang/Boolean.html#equals(java.lang.Object)) or `Boolean.FALSE.equals(myBooleanObject)`. – Christopher Peisert Jun 25 '12 at 08:20
  • 10
    A Boolean object has only two states -- `true` and `false`. `null` is ***not*** a state of the object, but rather a state of the object reference. – Hot Licks Jun 25 '12 at 20:04
  • *The only reason for the existence of Boolean is the ability to have collections of Boolean type* I'd say - to pass parameters via reflect, store caches (via Object[]); one should not use Collection/List etc w/ Boolean, BitSet and long[] are better suited; perhaps Map as set is the only passable use w/ generics. – bestsss Jun 25 '12 at 21:39
  • @cpeisert, this is how I use Boolean. btw another use is configs where Boolean denotes uninitialized/default value, it's for internal storage, the exposed methods are still `boolean` – bestsss Jun 25 '12 at 21:44
  • 1
    You should never use null for "the user didn't answer" because as Hot Licks says Boolean has only two states (so use another object/enum with all the states you need, in this case at least three). – osundblad Jun 28 '12 at 07:36
  • Why not use Boolean.valueOf() ? – codejammer Jun 29 '12 at 00:50
  • 2
    Leave to apache commons to be like "Someone might screw up evaluating booleans... let's make an `isTrue()` method..." which sounds like the dumbest freaking thing in the history of utility functions. And yet, somehow, it's useful... that's the biggest wtf here. – corsiKa Jul 06 '12 at 16:49
33

Wow, what on earth? Is it just me or are all these answers wrong or at least misleading?

The Boolean class is a wrapper around the boolean primitive type. The use of this wrapper is to be able to pass a boolean in a method that accepts an object or generic. Ie vector.

A Boolean object can NEVER have a value of null. If your reference to a Boolean is null, it simply means that your Boolean was never created.

You might find this useful: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Boolean.java

A null Boolean reference should only be used to trigger similar logic to which you have any other null reference. Using it for three state logic is clumsy.

EDIT: notice, that Boolean a = true; is a misleading statement. This really equals something closer to Boolean a = new Boolean(true); Please see autoboxing here: http://en.wikipedia.org/wiki/Boxing_%28computer_science%29#Autoboxing

Perhaps this is where much of the confusion comes from.

EDIT2: Please read comments below. If anyone has an idea of how to restructure my answer to incorporate this, please do so.

user606723
  • 4,918
  • 2
  • 27
  • 34
  • 3
    I don't understand your statement "A Boolean can NEVER have a value of null". I can create a Boolean (`Boolean a = true;`) and then set a to null (`a = null;`). It may not be elegant or wise, but it's possible. – peter.murray.rust Jun 25 '12 at 14:51
  • 7
    When you do `Boolean a`; a is a pointer to a Boolean object. If you `a = null;` You have not set your Boolean to null, you have set your reference to null. Do `Boolean a = null; a.booleanValue();` In this case, you ***never even created*** a Boolean object and therefore it'll throw a nullpointerexception. Let me know if you need further instruction. – user606723 Jun 25 '12 at 14:59
  • Further, when you do `Boolean a = true;`, It does some sort of magic that actually get interpreted as `Boolean a = new Boolean(true);` Thats probably not completely correct for performance reasons, but you have to realize that the Boolean is still an object. – user606723 Jun 25 '12 at 15:04
  • @user606723: No one cares if its a reference to a binary type or a ternary type. In the end, code that deals with Booleans will still have to deal with the null, Boolean(false) and Boolean(true) cases. – hugomg Jun 25 '12 at 16:49
  • 7
    @missingno, All code that deals with any object has to deal with this. An object reference can either be null or not. This isn't a special case and doesn't require special consideration. – user606723 Jun 25 '12 at 16:54
  • Of course it requires special consideration - if you don't you run the risk of running into a null pointer exception. Just because the language made the braindead decision to have nullable references by default doesn't mean you should go out of your way to defend that decision by pointing out that "null" is not a value of the variable. – hugomg Jun 25 '12 at 20:22
  • 3
    You're missing my point @missingno. I agree that we need to consider null reference values. I was never argueing against thatt. But we need to do this for **ANY OBJECT REFERENCE.** A null Boolean reference is not special case. And therefore null Boolean reference values don't require special consideration. – user606723 Jun 25 '12 at 20:34
  • Dont ever use "new Boolean(whatever)" as you instantiate a fresh copy of an immutable object cluttering up the heap. Instead use "Boolean.valueOf(whatever)" which creates a reference one singleton immutable value. For the smae reason you should use "Integer.valueOf(someint)". – simbo1905 Jul 01 '12 at 21:42
  • @simbo1905, Just to be clear, I wasn't advocating that. In fact, I doubt that's what autoboxing does. Thats why I said "something closer", impying uncertainty in what it does. I assume it does whatever would be better for performance which means reusing the same Boolean handle over and over again. Hell, I bet "new Boolean(whatever)" doesn't even do what it should in this case... it's probably optimized on the jvm side since this is such an elementary case of possible optimization. There can obviously be no benefit from doing a new Boolean(). – user606723 Jul 02 '12 at 02:27
26

There are three quick reasons:

  • to represent Database boolean values, which may be true, false or null
  • to represent XML Schema's xsd:boolean values declared with xsd:nillable="true"
  • to be able to use generic types: List<Boolean> - you can't use List<boolean>
Grzegorz Grzybek
  • 6,152
  • 3
  • 29
  • 42
  • I've explicitely wrote "boolean", not "`boolean`" (mind styling), because in Oracle you usually use `char(1) null` with 'T' and 'F' values. So it may (with e.g., Hibernate type adapter) be null :) – Grzegorz Grzybek Jun 25 '12 at 07:58
  • 2
    What database does not allow null for boolean? If you set the column to be nullable, the datatype does not matter anymore... – Michal B. Jun 25 '12 at 09:01
  • @MichalB. Sybase (and SQL Server) bit type http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.ase_15.0.blocks/html/blocks/blocks54.htm – mmmmmm Jun 25 '12 at 11:10
  • @Mark - no, SQL Server does allow a nullable bit - http://msdn.microsoft.com/en-us/library/ms177603.aspx – David M Jun 25 '12 at 14:56
11

ANSWER TO OWN QUESTION: I thought it would be useful to answer my own question as I have learnt a lot from the answers. This answer is intended to help those - like me - who do not have a complete understanding of the issues. If I use incorrect language please correct me.

  • The null "value" is not a value and is fundamentally different from true and false. It is the absence of a pointer to objects. Therefore to think that Boolean is 3-valued is fundamentally wrong
  • The syntax for Boolean is abbreviated and conceals the fact that the reference points to Objects:

    Boolean a = true;

conceals the fact that true is an object. Other equivalent assignments might be:

Boolean a = Boolean.TRUE;

or

Boolean a = new Boolean(true);
  • The abbreviated syntax

    if (a) ...

is different from most other assignments and conceals the fact that a might be an object reference or a primitive. If an object it is necessary to test for null to avoid NPE. For me it is psychologically easier to remember this if there is an equality test:

if (a == true) ...

where we might be prompted to test for null. So the shortened form is only safe when a is a primitive.

For myself I now have the recommendations:

  • Never use null for a 3-valued logic. Only use true and false.
  • NEVER return Boolean from a method as it could be null. Only return boolean.
  • Only use Boolean for wrapping elements in containers, or arguments to methods where objects are required
peter.murray.rust
  • 37,407
  • 44
  • 153
  • 217
  • 5
    Don't use "new Boolean(whatever)". That will instantiate a new Boolean on the heap. Yet Boolean is immutable. Use "Boolean.valueOf(whatever)" which will create a reference which points to either Boolean.TRUE or Boolean.False depending on whatever. – simbo1905 Jul 01 '12 at 21:43
  • 1
    One of many problems with Java (IMHO after 12 years) is inconsistency of approach to null values which old languages also have. Taking a look at Scala it has the concept of a typed Option which can be null or can have a value (subclasses None or Some). Then you can call myOption.getOrElse(defaultValue). See http://www.scala-lang.org/api/current/scala/Option.html there is nothing complex about this feature. Yet as it is built into the new JVM language many libraries use it. That makes scale "fix" some of the "last century" issue of Java but it still compiles to class files which run on the JRE. – simbo1905 Jul 01 '12 at 21:49
10

Wrapper classes for primitives can be used where objects are required, collections are a good sample.

Imagine you need for some reason store a sequence of boolean in an ArrayList, this can be done by boxing boolean in Boolean.

There is a few words about this here

From documentation:

As any Java programmer knows, you can’t put an int (or other primitive value) into a collection. Collections can only hold object references, so you have to box primitive values into the appropriate wrapper class (which is Integer in the case of int). When you take the object out of the collection, you get the Integer that you put in; if you need an int, you must unbox the Integer using the intValue method. All of this boxing and unboxing is a pain, and clutters up your code. The autoboxing and unboxing feature automates the process, eliminating the pain and the clutter.

http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
3

I suppose in some case, you should have a mechanism to distinguish a Boolean field which already set value or not.

Manroop
  • 301
  • 1
  • 3
  • 16
Thinhbk
  • 2,194
  • 1
  • 23
  • 34
3

Boolean wrapper is useful when you want to whether value was assigned or not apart from true and false. It has the following three states:

  • True
  • False
  • Not defined which is null

Whereas boolean has only two states:

  • True
  • False

The above difference will make it helpful in Lists of Boolean values, which can have True, False or Null.

Ramesh PVK
  • 15,200
  • 2
  • 46
  • 50
1

Main purpose for Boolean is null value. Null value says, that property is undefined, for example take database nullable column.

If you really need to convert everyting from primitive boolean to wrapper Boolean, then you could use following to support old code:

Boolean set = Boolean.FALSE; //set to default value primitive value (false)
...
if (set) ...
d1e
  • 6,372
  • 2
  • 28
  • 41
  • 6
    'The main purpose is null value'. No, the main purpose of Boolean is to pass a reference to a boolean as an object. – user606723 Jun 25 '12 at 14:06
  • @user606723 agreed, I was referring to the database case in my mind while I was writing. – d1e Jun 25 '12 at 14:08
1

There are many uses for the **null** value in the Boolean wrapper! :)

For example, you may have in a form a field named "newsletter" that indicate if the user want or doesn't want a newsletter from your site. If the user doesn't select a value in this field, you may want to implement a default behaviour to that situation (send? don't send?, question again?, etc) . Clearly, not set (or not selected or **null**), is not the same that true or false.

But, if "not set" doesn't apply to your model, don't change the boolean primitive ;)

dcasanueva
  • 29
  • 4
1

In a strict definition of a boolean element, there are only two values. In a perfect world, that would be true. In the real world, the element may be missing or unknown. Typically, this involves user input. In a screen based system, it could be forced by an edit. In a batch world using either a database or XML input, the element could easily be missing.

So, in the non-perfect world we live in, the Boolean object is great in that it can represent the missing or unknown state as null. After all, computers just model the real world an should account for all possible states and handle them with throwing exceptions (mostly since there are use cases where throwing the exception would be the correct response).

In my case, the Boolean object was the perfect answer since the input XML sometimes had the element missing and I could still get a value, assign it to a Boolean and then check for a null before trying to use a true or false test with it.

Just my 2 cents.

1

For all the good answers above, I'm just going to give a concrete example in Java servlet HttpSession class. Hope this example helps to clarify some question you may still have.

If you need to store and retrieve values for a session, you use setAttribute(String, Object), and getAttribute(String, Object) method. So for a boolean value, you are forced to use the Boolean class if you want to store it in an http session.

HttpSession sess = request.getSession(false);
Boolean isAdmin = (Boolean) sess.getAttribute("admin");
if (! isAdmin) ...

The last line will cause a NullPointerException if the attribute values is not set. (which is the reason led me to this post). So the 3 logic state is here to stay, whether you prefer to use it or not.

Karup
  • 2,024
  • 3
  • 22
  • 48
Wacker
  • 11
  • 2
1

Boolean can be very helpful when you need three state. Like in software testing if Test is passed send true , if failed send false and if test case interrupted send null which will denote test case not executed .

Aamir
  • 19
  • 1
  • 2
    Wouldn't enums be best for this? As opposed to possibly yielding unexpected NullPointerExceptions for a client, enums would explicitly define "states" – Kartik Chugh Mar 04 '17 at 03:22
  • Always prefer enums instead of booleans in state machines. You never know when a new fourth state arrives in the business requirement. – AnupamChugh Apr 26 '20 at 22:30
0

The best way would be to avoid booleans completely, since every boolean implies that you have a conditional statement anywhere else in your code (see http://www.antiifcampaign.com/ and this question: Can you write any algorithm without an if statement?).

However, pragmatically you have to use booleans from time to time, but, as you have already found out by yourself, dealing with Booleans is more error prone and more cumbersome. So I would suggest using booleans wherever possible. Exceptions from this might be a legacy database with nullable boolean-columns, although I would try to hide that in my mapping as well.

Community
  • 1
  • 1
Roland Schneider
  • 3,615
  • 3
  • 32
  • 43
  • Dealing with Booleans is as error prone as dealing with any other Object. BTW, the link is against the proliferation of IFs for type checking, not for general usage. And in turn, that is "dangerous" because it makes modifications more difficult. So there's nothing wrong with IFs per se. – Mister Smith Jun 25 '12 at 13:23
  • Not an answer to the question. – Matsemann Jun 25 '12 at 21:06
  • @MisterSmith Imho a boolean flag is often misused as a type checking variable, so the link can apply here, too. It should just be a hint that one should think about whether a boolean is the right tool in a certain situation. The statement "avoid booleans completely" is of course very radical and practically impossible, what is why I added the second paragraph. I have also added a "more error prone and more cumbersome" to clarify things. – Roland Schneider Jun 26 '12 at 10:10