Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joshua Bloch Item #1 Static Factory Methods Instead of Constructors - Object creation

Source of Question

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.

Question

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.?!

like image 849
citizen_code Avatar asked Oct 21 '25 13:10

citizen_code


1 Answers

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.

like image 181
WJS Avatar answered Oct 24 '25 04:10

WJS