Java boolean
allows values of true
and false
while Boolean allows true
, false
, and null
. I have
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.
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 ;)
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.
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.
true
and false
. It is the absence of a pointer to objects. Therefore to think that Boolean is 3-valued is fundamentally wrongThe 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:
Boolean
from a method as it could be null
. Only return boolean
.Boolean
for wrapping elements in containers, or arguments to methods where objects are requiredMain 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) ...
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.