While doing some code reviews I stumbled upon this:
People usually assign Boolean.TRUE
or Boolean.FALSE
value to a boxed boolean variable but use true
/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 true
/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.FALSE
/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.
When C extends D
, this means that a C
is-a D
, or that C
is a subtype of D
. When assigning an Integer
to Number
, no conversion is required, because an Integer
is-a Number
. Under the hood, both Integer
and Number
are represented by pointers (object references) and the assignment is just a pointer copy.
The relationship between boolean
and Boolean
is different, though. There is no extends
; there is no is-a. Instead, there are boxing and unboxing conversions, which get applied in certain contexts (e.g., assignment, method parameters.) Their representations are different. So when you convert between boolean
and 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;
or
Boolean bb = Boolean.TRUE;
the types on both sides of the =
are the same -- boolean
in the first example, Boolean
in the second -- and there is no conversion. When you do
boolean b = Boolean.TRUE;
or
Boolean bb = true;
the types are different, and there is a conversion required. The compiler silently translates these to:
boolean b = Boolean.TRUE.booleanValue();
and
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.TRUE
and 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With