(For the purposes of this question, let us assume that one is intentionally not using auto(un)boxing, either because one is writing pre-Java 1.5 code, or because one feels that autounboxing makes it too easy to create NullPointerException
s.)
Take Boolean
, for example. The documentation for the Boolean(boolean)
constructor says:
Note: It is rarely appropriate to use this constructor. Unless a new instance is required, the static factory
valueOf(boolean)
is generally a better choice. It is likely to yield significantly better space and time performance.
My question is, why would you ever want to get a new instance in the first place? It seems like things would be simpler if constructors like that were private. For example, if they were, you could write this with no danger (even if myBoolean
were null
):
if (myBoolean == Boolean.TRUE)
It'd be safe because all true Booleans
would be references to Boolean.TRUE
and all false Booleans
would be references to Boolean.FALSE
. But because the constructors are public, someone may have used them, which means that you have to write this instead:
if (Boolean.TRUE.equals(myBoolean))
But where it really gets bad is when you want to check two Booleans
for equality. Something like this:
if (myBooleanA == myBooleanB)
...becomes this:
if (
myBooleanA == myBooleanB ||
(myBooleanA != null && myBooleanA.equals(myBooleanB))
)
UPDATE: With the release of Java 7, java.util.Objects makes this simpler construct possible:
if (Objects.equals(myBooleanA, myBooleanB))
I can't think of any reason to have separate instances of these objects which is more compelling than not having to do the nonsense above. What say you?
For example, String is an immutable class. Hence, we cannot change the content of a string once created.
net. URL is not immutable as many of its fields are not final.
The cached values are never garbage collected, so use the constructors whenever you'd like to use them as soft/weak references, so that it can be garbage collected anyway whenever needed. The same applies on Long#valueOf()
, Integer#valueOf()
and consorts with values within cacheable ranges.
Doing a reference search in Eclipse learns me that under each java.lang.Thread
uses new Boolean()
as a soft-reference based cache, it's even explicitly commented (in isCCLOverridden()
method):
/*
* Note: only new Boolean instances (i.e., not Boolean.TRUE or
* Boolean.FALSE) must be used as cache values, otherwise cache
* entry will pin associated class.
*/
The constructors are public because of backwards compatibility... .valueOf() only got added in java 1.4...
Also using a Boolean as a tri-state variable in your example (null/TRUE/FALSE) is probably a bad idea -- better to use an enum (UNKNOWN,TRUE,FALSE), or if null is not a valid value, check for it, and manually unbox for testing equality.
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