tags:

views:

967

answers:

7

If you have a situation where you need to know where a boolean value wasn't set (for example if that unset value should inherit from a parent value) the Java boolean primitive (and the equivalent in other languages) is clearly not adequate.

What's the best practice to achieve this? Define a new simple class that is capable of expressing all three states or use the Java Boolean class and use null to indicate the unset state?

+10  A: 
Boolean a = true;
Boolean b = false;
Boolean c = null;

I would use that. It's the most straight-forward.

Another way is to use an enumeration. Maybe that's even better and faster, since no boxing is required:

public enum ThreeState {
    TRUE,
    FALSE,
    TRALSE
};

There is the advantage of the first that users of your class doesn't need to care about your three-state boolean. They can still pass true and false. If you don't like the null, since it's telling rather little about its meaning here, you can still make a public static final Boolean tralse = null; in your class.

Johannes Schaub - litb
The Daily WTF website says that the 3rd value should be named "FILE_NOT_FOUND". See: http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
Darron
I'd go with the Boolean, myself. The whole TRUE, FALSE, FILE_NOT_FOUND/TRALSE thing is just asking for trouble.
Paul Tomblin
Bad design. Make a tri-state object. Instantiate it with the parent to automate value inheritance when "unset", otherwise that test/use parent is going to be spread throughout your code.
Bill K
Bill, i'm not a java programmer. feel free to post your solution in your answer. i will upvote it if it's nice :)
Johannes Schaub - litb
Is this a good design or bad one -- depends on the context. No reason to over complicate things if all you need is an "N/A" flag in one piece of the code.
Vladimir Dyuzhev
I didn't do this but instead made wrapper class called Property that held the unset state. This is because I had other types with the same requirement, (Integer and Color). For each one the unset state could have been represented with null though.
Tom Martin
+5  A: 

Although not Java-specific, my own preference in this scenario is to define a ThreeState class or enumeration and use it -- just as you mentioned, a True, a False and an Undefined (or Default, or Unset, as your domain-specific terminology dictates). It feels better, more natural and more self-documenting than representing unset/undefined with null.

John Rudy
This is absolutely the way to go. Also, you can refer to the "Parent" in your class so that you can automatically inherit it's state. Otherwise you have the "inherit state" code spread throughout your code (not DRY).
Bill K
Bill, what the heck do you mean by "Parent" ?
Johannes Schaub - litb
A: 

java.lang.Boolean does this for you. There are static constants Boolean.TRUE, Boolean.False.

private Boolean myBoolean;

should be all you need.Note that Boolean.TRUE will pass an equivalence test but is distinct from "true" (which gets autoboxed to TRUE).

Steve B.
+5  A: 

The nullable boolean gets my vote

Chris Simpson
A: 

It depends. Here you mention it would be unset if it has to inherit its value from a parent value. Do you have some kind of data hierarchy? Something like this:

Parent a { 
    boolean val = true;
    boolean val2 = false; 
}
Child b {
    boolean val = false;
    //here val2 should be unset!
}

In this case, if it's possible, I'd say simply don't include val2 in the Child, and have your lookup logic be such that if it doesn't find the variable, it searches the parents for the value.

Claudiu
A: 

Using nulls to represent the state of something is poor design. It's undescriptive and hard to maintain. I would rather have a State object with a default state if nothing has been explicitly set on it. For example:

if(state == null) {
    doSomething();
}

This doesn't tell me anything about what the expected state is. Something more like this makes it more clear.

if(state.awaitingSet()) {
    doSomething();
}

Not to mention extensible. What happens when you need a fourth state?

Hates_
A: 

In the Parent class initiate the boolean to null and in the child class build a method to check to see if the boolean has been set

in Parent class

private Boolean a = null;

public void setA(Boolean a) {
 this.a = a;
}


public Boolean getA() {
 return a;
}

In the Child Class

if (a == true)
{
dothis;
}
else if (a == false)
{
dothat;
}
else
{
assert false : "Boolean a has not been set";
}

Make sure that assertions are turned on. Assertions are only for the development cycle and test cycle, they are not for runtime exceptions.

WolfmanDragon