I was wondering about the following advantage of Static Factory Methods described by Joshua Blochs "Effective Java", 3rd edition in item #1:
A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked. This allows immutable classes (Item 15) to use preconstructed instances, or to cache instances as they’re constructed, and dispense them repeatedly to avoid creating unnecessary duplicate objects. The Boolean.valueOf(boolean) method illustrates this technique: it never creates an object.
See extract here.
What got my attention was the last line about valueOf(boolean)
not creating an object.
According to the book
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
and the Javadoc
public static Boolean valueOf(boolean b)
Returns a Boolean instance representing the specified boolean value. If the specified boolean value is true, this method returns Boolean.TRUE; if it is false, this method returns Boolean.FALSE. If a new Boolean instance is not required, this method should generally be used in preference to the constructor Boolean(boolean), as this method is likely to yield significantly better space and time performance.
So from my understanding and the Javadoc ("Returns a Boolean instance...") the static method returns indeed a Boolean and therefore an object - as it is literally the return type. In the following case:
public class MyClass {
public static void main(String args[]) {
Boolean booleanWrapped = Boolean.valueOf(true);
System.out.println(booleanWrapped);
}
}
booleanWrapped
is my object I can use e.g. like in the prinln()
statement.
So what am I missing here if Joshua states
The Boolean.valueOf(boolean) [...] never creates an object
I'm aware of a similar question with an existing answer but it doesn't seem to fully answer my question as in my example above there isn't an "pre-existing" instance.?!
As of Java 9, Boolean has a deprecated constructor. But this still demonstrates the difference.
So Boolean b1 = new Boolean(true).
creates a new instance and stores it in b1
.
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean(true);
System.out.println(System.identityHashCode(b1));
System.out.println(System.identityHashCode(b2));
Two different identity hashcodes imply different objects
804564176
1421795058
Now use the existing static instance.
Boolean b1 = Boolean.TRUE;
Boolean b2 = Boolean.TRUE;
System.out.println(System.identityHashCode(b1));
System.out.println(System.identityHashCode(b2));
Sharing the same object - same hashcode.
804564176
804564176
Within the Boolean class you have the following:
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
So they are created when the class is loaded.