Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would one want to use the public constructors on Boolean and similar immutable classes?

(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 NullPointerExceptions.)

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?

like image 614
Robert J. Walker Avatar asked Apr 08 '10 16:04

Robert J. Walker


People also ask

Which of the following is an example of an immutable class?

For example, String is an immutable class. Hence, we cannot change the content of a string once created.

Which one is not an example of an immutable class?

net. URL is not immutable as many of its fields are not final.


2 Answers

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.
 */
like image 65
BalusC Avatar answered Oct 16 '22 11:10

BalusC


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.

like image 1
RedPandaCurios Avatar answered Oct 16 '22 09:10

RedPandaCurios