While doing some code reviews I stumbled upon this:
People usually assign
Boolean.FALSE value to a boxed boolean variable but use
false for primitive variables. What is the best way for this?
According to an architect I worked with – he said that every time you assign
false to a variable a new instance of Boolean is created. We can skip that if we assign the boolean variable to the static instances –
Boolean.TRUE. If the variable is primitive an auto-unboxing is done.
Is the auto-unboxing faster than the initialization of a boolean variable? The differences are not big and I think this is just a micro-optimisation of the code but I wanted to learn more about this.
You are right that the performance concerns are mostly a distraction.
To understand what is going on, let’s look at how primitives and their boxes are modeled in the Java type system.
C extends D, this means that a
D, or that
C is a subtype of
D. When assigning an
Number, no conversion is required, because an
Number. Under the hood, both
Number are represented by pointers (object references) and the assignment is just a pointer copy.
The relationship between
Boolean is different, though. There is no
extends; there is no is-a. Instead, there are boxing unboxing conversions, which get applied in certain contexts (e.g., assignment, method parameters.) Their representations are different. So when you convert between
Boolean, the form changes (from a direct representation of the boolean value, to a pointer to a heap node containing an object header and a boolean payload.) This is why people warn you about “the performance cost”; it’s not just copying one word. (That said, if this is the performance bottleneck in your program, you’ve got bigger problems — namely that your program doesn’t do very much.)
When you assign
boolean b = true;
Boolean bb = Boolean.TRUE;
the types on both sides of the
= are the same;
boolean in the first example,
Boolean in the second. When you do
boolean b = Boolean.TRUE;
Boolean bb = true;
the types are different, and there is a conversion required. The compiler silently translates these to:
boolean b = Boolean.TRUE.booleanValue();
Boolean bb = Boolean.valueOf(true);
In the specific case of
boolean, the performance concerns are even less relevant than for other primitives, since there are only two boolean values, and the constants
Boolean.FALSE are interned.
If your architect gave you this advice primarily on performance concerns, then he/she was misguided. If their advice was motivated more by simplicity — that it is equally easy to use a value of the correct type that requires no conversion — this is sensible.