What the difference between Boolean.TRUE and true - java

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.

Related

Why does Integer.class.isInstance(i) return true while int.class.isInstance(i) and Integer.TYPE.isInstance(i) return false?

What is the difference between Integer.class, int.class and Integer.TYPE? I am kind of confused between the three.
Whether i is an int or an Integer:
Integer.class.isInstance(i) returns true
int.class.isInstance(i) returns false
Integer.TYPE.isInstance(i) returns false
Let's understand isInstance.
public boolean isInstance(Object obj)
Determines if the specified Object is assignment-compatible with the object represented by this Class.
It takes an Object as an argument, not a primitive type. Any int passed in will be boxed as an Integer so it can be passed to the method.
Integer.class is a class literal, and used with a reference type, that is a reference to the Class object for that class.
The Integer object that this method sees certainly is an instance of the Integer class, so Integer.class.isInstance(i) returns true.
However, int.class and Integer.TYPE each represent the int primitive type, not the Integer class, and an Integer is not an int, despite the fact that Java usually uses them interchangeably, due to boxing and unboxing. This explains the two false outputs from int.class.isInstance(i) and Integer.TYPE.isInstance(i).
Class literal history
According to the Javadocs for Integer, Integer.TYPE has been around since version 1.1.
But class literals have also been around since 1.1.
Java APIs which require class objects as method arguments are much easier to use when the class literal syntax is available.
The class literals made it tremendously easier to use reflection, which was also new in Java 1.1.
It is unclear why Integer.TYPE exists if int.class represents the int primitive type consistently with reference class literals. They are equivalent and == yields true when comparing them.

Java references and primitives

In Java, when we assign an object to a variable of the matching class type, the variable only contains a reference to the memory location where the object in stored.
Is the case same with Primitive data types as well?
I mean, in int i = 10;, does i store the address of the memory location where the value 10 is stored?
PS: In sharp contrast, C++ actually stores the objects and not the references, right? Unless we use pointers and reference variables, right?
In Java, everything is stored by value. The value of an Object type in contrast to a primitive is the reference. Note that the wrapper types (like Integer) do constant interning for low values.
Indeed, in Java, primitives are always handled by value and objects are always handled by reference. Note however that these are the semantics; i.e., what the meaning of Java code is supposed to be. A particular implementation of Java (i.e., a JVM) is free to manage memory however it likes internally, as long as it appears to obey the correct semantics for anything that can be observed (i.e., output of the program).
And your PS remark is also correct.

What is the difference between false and Boolean.FALSE?

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");
}

primitives vs wrapper class initialization

What is the Difference between declaring int's as Below. What are the cases which suits the usage of different Types
int i = 20;
Integer i = 20;
Integer i = new Integer(20);
Please Note : I have goggled and found that first is going to create primitive int.Second is going to carry out auto boxing and Third is going to create reference in memory.
I am looking for a Scenario which clearly explains when should I use first, second and third kind of integer initialization.Does interchanging the usage is going to have any performance hits
Thanks for Reply.
The initialization in the 1st case is a simple assignment of a constant value. Nothing interesting... except that this is a primitive value that is being assigned, and primitive values don't have "identity"; i.e. all "copies" of the int value 20 are the same.
The 2nd and 3rd cases are a bit more interesting. The 2nd form is using "boxing", and is actually equivalent to this:
Integer i = Integer.valueOf(20);
The valueOf method may create a new object, or it may return a reference to an object that existed previously. (In fact, the JLS guarantees that valueOf will cache the Integer values for numbers in the range -128..+127 ...)
By contrast new Integer(20) always creates a new object.
This issue with new object (or not) is important if you are in the habit of comparing Integer wrapper objects (or similar) using ==. In one case == may be true if you compare two instances of "20". In the other case, it is guaranteed to be false.
The lesson: use .equals(...) to compare wrapper types not ==.
On the question of which to use:
If i is int, use the first form.
If i is Integer, the second form is best ... unless you need an object that is != to other instances. Boxing (or explicitly calling valueOf) reduces the amount of object allocation for small values, and is a worthwhile optimization.
Primitives will take default values when declared without assignment.
But wrapper classes are reference types, so without assignment they will be null. This may cause a NullPointerException to be thrown if used without assignment.
One such scenario I can think of is when you are mapping DB types in Hibernate. If you use Integer you can check for null (assuming the column allows null values). If you use primitive and if the value is null in the database, I guess it throws an error.

Why does autoboxing in Java allow me to have 3 possible values for a boolean?

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.

Categories

Resources