As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
So, according to wikipedia and others, a boolean values should have only 2 states: 0 or 1; true or false; yes or no; and so on...
OK, correct me if I'm wrong, but, Java Boolean wrapper let developers have 3 states: true, false and null.
Isn't that wrong?
I know that it could be explained with something like "Boolean is an object" etc etc, but, it would be really great if javac automagically "wrap" null to false, IMHO.
My point is: this behavior let developers do a lot of crap, because they use Boolean instead of a proper object type.
Anyway, what do you think about it? Am I following a wrong line of thinking.. or is it really "wrong"?
EDIT
I know what is null, the differences between boolean and Boolean, etc etc etc (I have 3-year+ exp with java).
My point is about the concept itself, like in Ruby, for example, if I do something like if something, if this something instance is nil, it will be false.
And I'm not saying that Java is crap or something like, I use it everyday.
null represents the absence of a value, whereas true and false are definite values. It's the difference between knowing something, either affirmatively or negatively, and not knowing it at all. That's one way to think of it.
Technically the reason a Boolean can be null is because it's an object reference, not a boolean value itself, a confusion that autoboxing might be causing for you. It used to be that you had to manually create Boolean objects to contain boolean values and manually extract the boolean values from Boolean objects. Since Java 5, the compiler will take care of this for you.
The value of the boolean contained by a Boolean object can either be true or false, but an object variable may not be pointing to an object at all, in which case the value of the reference is null.
Why is there a difference between boolean and Boolean you might ask? Well, in Java, unlike a lot of newer languages, the primitive types are not classes, and primitives are not objects. When you want to treat them as such, like when you want to pass by reference or call methods on them or put them in collections, you have to box them up in their respective primitive wrapper classes.
If the tri-valued nature of Boolean isn't right for you, don't use it. Use boolean. There are times when you need Boolean, when you are working with an Object-oriented interface. When that happens, you use Boolean.
boolean is a primitive type which represents the concept you are describing, a type with two possible values: true and false.
Boolean is different type. It's an Object which holds a boolean value. If the object doesn't exist, then the reference is null. It's not the boolean object which is null, it's the reference to a boolean object which is null.
Though their names are similar, don't conflate boolean and Boolean. They are distinct types for good reason.
Since you have a boolean which can be two states, it doesn't make sense to use Boolean unless
you need the three states
you are using an API which means you have to.
In general, always use a primitive if you can unless a) you need a null value b) you have to due to an API.
What you imply is that a wrapper should mimic the strict behavior of the primitive 'real' boolean. Thats the problem. A Boolean is not conceptually the same as a boolean (note capitalization).
The primitive boolean provides what is described in Wikipedia as a boolean.
The Boolean (java.lang.Boolean) is not called a wrapper just for show. It is conceptually an Object that contains a boolean. So references to a Boolean are references, nothing in common with a boolean. Thus the rules for references apply, not primitives.
Its quite simple and logical if you take this viewpoint.
You are confusing with primitive boolean and primitive wrapper Boolean. Indeed boolean can be true or false only.
Boolean instance can hold true or false too. But if instance does not exist the reference is null as any not initialized reference.
null means "I don't have an object here". The Boolean true object is a wrapper around the primitive boolean true, but it is still an object. Note that the following code throws a NullPointerException
public static void main(String[] args) {
Boolean myBool = null;
boolean primBool = myBool;
System.out.println(primBool);
}
Null makes it nullable , when you create a database for example it has a table with below columns :
Col-1 : Hour (nvarchar)
Col-2 : Minute (nvarchar)
Col-3 : IsDay (bool)
So if the hour is 18 and minute is 00 what is the value for IsDay ? (it is nor true or false) it is null at this time...
Related
I just saw a code from another developer.
private static boolean _menuNeedsUpdate = false;
private static Boolean _userIsLoggingIn = Boolean.valueOf(false);
I want to know the differences between these two declarations. Can any one please clarify this?
The first one is a primitive boolean with default value false.
The second one is a Wrapper class of Boolean with default value false.
Apart, I can't see any more difference.
Edit : (Thankyou #carsten #sasha)
Apart from the declaration, another point worth mentioning is with the second declaration the value of _userIsLoggingIn may become null later on where as the primitive cannot.
yes you can use Boolean/boolean instead.
First one is Object and second one is primitive type
On first one, you will get more methods which will be useful
Second one is cheap considering memory expense.
Now choose your way
Frist one is java primitive and second one is an object/refrence types that wraps a boolean.
Converting between primitives and objects like this is known as boxing/unboxing.
boolean can be yes or no.
Boolean can be yes, no or NULL.
boolean is a literal true or false, while Boolean is an object wrapper for a boolean.
There is seldom a reason to use a Boolean over a boolean except in cases when an object reference is required, such as in a List.
Boolean also contains the static method parseBoolean(String s), which you may be aware of already.
More info :
What's the difference between boolean and Boolean in Java?
As others said, the first declaration is a primitive while the second is wrapper class.
I would like to add that the second declaration creates a warning when using Java 5 or newer.
Declaring _userIsLoggingIn like
private static Boolean _userIsLoggingIn = false;
instead of
private static Boolean _userIsLoggingIn = Boolean.valueOf(false);
will use Boolean.FALSE, avoiding the creation of a new Boolean instance
Firstly, I have
private Map<String, Boolean> mem = new HashMap<String, Boolean>();
And then:
if (wordDict.contains(s) || Boolean.TRUE==mem.get(s)) {
return true;
}
why can't I use "mem.get(s)==true" in the if statement. There will be a error "Line 6: java.lang.NullPointerException"
I think I still cannot understant wrapper class well. Please give me some guidance. Thank you!
if mem.get(s) is null and will be compared with a primitive boolean value, java will make autoboxing. It means it will call null.booleanValue().
Thats why you get a NPE.
looks that mem.get(s) returns Boolean type result. In java there are two types for handling logical values. Boolean object type and boolean primitive type.
To evaluate logical expression for if statement, java converts Boolean to boolean using autoboxing.
But if your method returns null instead of Boolean object, then java is unable to unbox this value to boolean primitive type. And you get NullPointerException.
This is more a logical problem than a languagebased. if(mem.contains(s) || Boolean.TRUE == mem.get(s)) will only check the second part of the condition, if s isn't in mem. Thus the comparison is equivalent to Boolean.TRUE == null. Since Boolean.TRUE is a Boolean object, the comparison is between two references (and will always return false). boolean on the other hand is a primitive type and thus the Boolean retrieved from mem has to be converted first. Since it's null it can't be converted to the primitive type.
Any time the dictionary does not contain s (wordDict.contains(s) is false), the second condition (mem.get(s) == true) is evaluated.
In Java's library Maps, attempting to obtain the value for a key which isn't present returns null. So every time that key isn't in the mem map, null is returned, and compared (using ==) with true. When the Boolean type gets compared with, or assigned to, a boolean value, it is 'autounboxed'. This means the Boolean.booleanValue() method is called. If the Boolean is null, this is what causes the exception, because it means calling null.booleanValue(). null is not anything, so it doesn't know how to be a boolean!
The wrapper classes are useful constructs which enable the primitive types to interoperate with types inheriting from Object, that is, reference types (everything else). When you deal with primitive types ('value' types), their values are directly present in the location they're described in - either as part of the memory being used to execute the current function (for local variables) or as part of the memory space allocated to an object in its memory space (for field variables). When you deal with reference types (those inheriting from Object, including Boolean and the other wrapper types), the data being referred to instead exists in a memory space called the Heap. Alongside this Heap memory allocation, in order to know where that object is, the entity analogous to the value for value types is in fact a reference to the memory location of the object, stored as a local variable or a field variable, not the value or data of the object itself. This is what enables these to be null: a null reference says that this variable points to nothing in particular. (Read about Stack and Heap allocation for more detail.)
The reason you're safe comparing to Boolean.TRUE is because on Object types, like Boolean (and any of the wrapper classes for primitive types), the variable of type Boolean is in fact a reference. This means the == operator is actually checking if the references are the same - i.e. if the actual object in memory is the same one (has the same memory location), not if they are 'equal' by some value-based definition of 'equal'. You don't want this, because you can get surprising results like new Boolean(true) == new Boolean(true) returning false. This is incidentally why we have the equals method - this should be defined by any class for an object that wants to be compared by value rather than by reference. On the other hand, for the primitive value types, like boolean, the == operator literally compares the value. This is why it's useful to have the wrapper types box and unbox automatically - a Boolean variable (without being 'dereferenced' - finding the value it points to) is actually a reference value, referring to a memory location. A boolean variable is an actual boolean value. Hence, without unboxing and boxing automagically, it would make no sense to try to compare the two.
If you want to make sure that the value of mem.get(s) is neither null, nor false, use something like mem.containsKey(s) && mem.get(s) == true. The first check ensures that there will be no null reference.
In C++ windows.h FALSE is defined as integer which makes sense for some special logic cases, but in Java java.lang.Boolean.FALSE is defined as boolean and assigned to false
public static final Boolean FALSE and I've seen some people use it.
My question: is there a performance difference between false and Boolean.FALSE? in general why do people go and Boolean.FALSE?
See http://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html.
Boolean.TRUE and Boolean.FALSE are not boolean, they are Boolean. They are static instances of the two Boolean wrapper objects that correspond to the boolean values true and false.
Boolean is similar to an enum. The TRUE and FALSE instances are the instances returned by Boolean.valueOf().
As for performance of primitive vs. wrapper; there is no difference that you would ever need to be concerned about. The TRUE and FALSE static instances help performance a bit, and the javadocs recommend using Boolean.valueOf() as opposed to new Boolean(...) for that reason. The true and false boolean values are a little "lower level", but if you are storing them in a Boolean (as opposed to boolean) anyways it's irrelevant.
You should use whichever makes the most sense for your code and leads to the best readability (and definitely don't start going down the path of thinking of microoptimizations like primitive vs. wrapper types). If you are using a Boolean, use the object values. If you are using a boolean, use the primitive values. If you are deciding between Boolean vs boolean, use whatever is more appropriate (e.g. a Boolean can be null, which may be useful, and also you can't use primitive types for generic type parameters; on the other hand, a boolean can never be null which could be equally useful).
Also note that auto boxing converts the primitive types to one of those two static Boolean instances, e.g.:
Boolean a = true;
assert(a == Boolean.TRUE);
As an aside, since you mentioned it: FALSE is defined in windows.h for two reasons: 1) Because windows.h has been in use since C-only days, and C does not have a native bool type, and 2) it is traditional Microsoft practice to define data types and values with known, explicit sizes and values, esp. for passing data to Windows API functions across DLL boundaries (beyond the scope of this question) and for integrating with other languages that have different representations of "true" and "false". It is entirely unrelated to the reasons for Boolean.FALSE in Java.
false is a primitive and Boolean.FALSE is an object, so they're not really comparable.
If you assign false to a Boolean variable, like this:
Boolean b = false;
Java's auto boxing occurs to convert the primitive into an object, so the false value is lost and you end up with Boolean.FALSE anyway.
In terms of performance, using a primitive variable would slightly out-perform using a wrapper Boolean object, but your choice should be based on readability and basic design decisions rather than on "performance".
Boolean comes in handy when you need a tri-state variable.
Also, you might want to check out this autoboxing and unboxing tutorial, as well as the rules for how it works.
It is a very strange question, because false is the value of primitive type boolean, while Boolean.FALSE is a variable of reference type Boolean. Its value is reference to the object of type Boolean which internal boolean state is false.
In regards to performance, Boolean.FALSE will return a Boolean object, which might give you more flexibility to work with.
The primitive alternative takes up less memory
First of all, if you are unclear with this, you need to know that in Java numericals cannot be implicitly cast to booleans, e.g. you cannot compile something like:
int a = 1;
if(a){
//something, something
}
Second, some considerations about performance.
There's always a tradeoff.
When using primitive type boolean, performance should be better because you're using a value directly, which is either true or false (obviously, byte-encoded).
When using object type Boolean, a variable/field will hold a value, but that value cannot be immediately used, as that value is in fact the reference to an object, so you might have a performance penalty. Of course, this penalty is not significant in most cases. And, if you develop a time-critical application, most likely you are not using Java :). Nevertheless, using object types might bring some benefits in development process and safety in use cases implementation (e.g. it allows nulls, which is critical when you map JPA entities to relational tables and there are bit-typed columns that allow nulls; and this is only one scenario where object type is better).
In the end, be aware of boxing/un-boxing, which allows developers to use boolean-typed variables almost everywhere a Boolean-typed variable is expected (and the other way around).
Boolean is wrapper class for boolean primitive type, same as we have Integer for int.
Boolean has many methods to play around primitive type boolean
http://docs.oracle.com/javase/6/docs/api/java/lang/Boolean.html
Boolean a = null;
if (a) {
// NullPointerException
}
if (a != false) {
// NullPointerException
}
// Caution, comparing by reference, meaning 2 Booleans with same value could be different
if (a != Boolean.FALSE) {
System.out.println("But this one works");
}
I am reading Effective Java and in the first chapter the first example changes a boolean primitive value into a boolean object reference:
public static Boolean valueOf(boolean b)
{
return b ? Boolean.TRUE : Boolean.FALSE;
}
My questions are:
What is the different between boolean primitive value and boolean object reference?
What is the reason to do this?
You cannot use primitives in generics. You cannot do this:
List<boolean> x;
but you can do this:
List<Boolean> x;
Remember that the primitive boolean has two possible values: true or false. The object Boolean has three: true, false, and null. That is sometimes very useful.
A primitive cannot be used in all contexts. For instance, when used in any of the collection classes, an object type is required. This is mostly done for you, anyway, by auto-boxing. But you should still know about it, or you will get bitten at one point.
Another thing is that an object type can contain null. In cases where you need to differentiate between true, false and unknown, using Boolean can be an easy solution.
1> Boolean is wrapper class for boolean
Wrapper classes are used to represent primitive values when an Object
is required. Wikipedia
wrapper class is used to apply some methods and calculation, which is not possible using primitive data types.
2> it depends upon situations.
I believe the most common uses for Boolean are for use in generic function object and, unfortunately, reflection.
For instance:
boolean exists = java.security.AccessController.doPrivileged(
new PrivilegedAction<>() {
public Boolean run() {
return file.exists();
}
}
);
(Probably less boilerplate in Java SE 8.)
Reference: http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html
"If your program tries to autounbox null, it will throw a NullPointerException."
javac will give you a compile-time error if you try to assign null to a boolean. makes sense. assigning null to a Boolean is a-ok though. also makes sense, i guess.
but let's think about the fact that you'll get a NPE when trying to autounbox null. what this means is that you can't safely perform boolean operations on Booleans without null-checking or exception handling. same goes for doing math operations on an Integer.
for a long time, i was a fan of autoboxing in java1.5+ because I thought it got java closer to be truly object-oriented. but, after running into this problem last night, i gotta say that i think this sucks. the compiler giving me an error when I'm trying to do stuff with an uninitialized primitive is a good thing. I dont want to use autoboxing if I lose that.
I think I may be misunderstanding the point of autoboxing, but at the same time I will never accept that a boolean should be able to have 3 values. can anyone explain this? what am i not getting?
Boxed types are reference types, and all reference types, primitive boxes or not, can refer to null. That's why a Boolean can refer to null. So can an Integer. So can a String, etc.
Boxed types are not designed to make Java truly object oriented. Java will never be a purely object oriented language, and you should not code as if this is the case. Primitive types will never go away, and in fact should be preferred whenever there's a choice.
Here's a quote from Effective Java 2nd Edition, Item 49: Prefer primitive types to boxed primitives (emphasis by author):
In summary, use primitives in preference to boxed primitive whenever you have the choice. Primitive types are simpler and faster. If you must use boxed primitives, be careful! Autoboxing reduces the verbosity, but not the danger, of using boxed primitives. When your program compares two boxed primitives with the == operator, it does an identity comparison, which is almost certainly not what you want. When your program does mixed-type computations involving boxed and unboxed primitives, it does unboxing, and when your program does unboxing, it can throw NullPointerException. Finally, when your program boxes primitive values, it can result in costly and unnecessary object creations.
I've seen at least one case where the null value is useful. Lots of data objects in webservices have nullable boolean fields. Sometimes the user neglects to include a value. In this case you want to be able to discern the lack of a value from a default value. Previously, people would write getX, setX, and isXSet() methods, where isXSet returns false until someone calls setX. Now it's possible to make X be a nullable type and it's clear that it wasn't set if getX returns null.
In addition to everything said here, there are cases where you would very much want to have a third value for booleans - the case of an "optional" property.
We usually encounter it with databases, with boolean columns that allow nulls. Without using Booleans, we would need to use two separate variables, one indicating the value and another whether it is valid.
In fact, if you look at the JDBC API, you can see an example of this problem, where columns get a default value if they are null (e.g., a 0 for numeric fields), and then you have to call "wasNull" to check whether it is a true 0 or a fake null!
Your issue is with autounboxing, not autoboxing. I think autounboxing is evil for more significant reasons:
Consider this:
Integer i = new Integer(1);
Integer i2 = new Integer(12);
System.out.println(i == 10 || i != i2);
One == unboxes and the other doesn't.
Unboxing on operators (as opposed to assignments) was a mistake in my view (given the above - it is just not Java). Boxing, however, is very nice.
I think it's more philosophical than technical question. When you transform primitive type to reference type you should be ready that reference types (i.e. objects) are nullable.
You can watch The Billion Dollars Mistake presentation where C.A.R. Hoare says that his introducing null references to oop (Algol 60) was a mistake.
Josh Bloch in Effective Java recommends to prefer primitive types where it's possible. But sometimes you do have to verify you Boolean variable against null.
There is actually no big difference to the days before Java 1.5 - the problem is not the boolean type (it still has two states) but the Boolean wrapper (which always had 3 states. Boolean.TRUE, Boolean.FALSE and null).
Every conversion from a Boolean object to the boolean primitive requires null checks, with or without autoboxing.
Autoboxing automatically transforms data types between intrinsic types and Object types.
Object types for Boolean can be Boolean.TRUE, Boolean.FALSE, or null. That's why you have to deal with the possible 3 values for a boolean.
In databases, it is common to have three states for a boolean type. Consider a record that tracks whether someone has passed a class. There's TRUE, for passing; FALSE for not passing, and NULL for "currently taking the class". Yes, it's odd, but not having a value is inherit in object oriented programming.
I too find autoboxing a bit distasteful, mainly because it is a feature where the compiler adds bytecode to handle the conversion process. In my opinion, this can lead to people forgetting about important details in the conversion process which might be better remembered (such as the null handling in your case). It is useful, but not nearly as useful as most other features of the Java language.
Personally, I wish that the intrinsics were implemented as lightweight objects instead of "built-in" types. There's a lot of times where the hybrid intrinsic / object type system gets in the way. That said, intrinsics were supposed to be there to improve performance, but it seems that if you must do a lot of intrinsic to Object marshalling, you can't enjoy the intrinsic-only performance boost.
It is the problem with autoboxing, just like Integer i = null;. Integer object can be null while a native int cannot be.
It was never intended, with the introduction of autoboxing, that it replace the primitives. In most places primitives are what you want. If you want to start using the reference types because "it got java closer to be truly object-oriented" then that's your call, but as you are discovering, there are disadvantages with that approach. Performance will be another issue.
Autoboxing (and autounboxing) is there to help with the transitions between code that uses primitives (the majority) and the code that has to use reference types (rare). Of the reference types, Boolean is undoubtedly the rarest, since its small number of instances mean it's almost never worth putting in a Collection.
In summary: if the reference types are causing you trouble, don't use them. But don't say 'autoboxing is bad" just because they turned out not to be helpful in your situation.