Saturday 7 July 2012

Item 1: Consider static factory methods instead of constructors


A class can provide a public static factory method, which is simply a static method that returns an instance of the class.

public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}

Providing a static factory method instead of a public constructor has both advantages and disadvantages.

Advantages:
1)    Unlike constructors, they have names.
2)    Unlike constructors, they are not required to create a new object each time they’re invoked.
3)    Unlike constructors, they can return an object of any subtype of their return type.
4)    They reduce the verbosity of creating parameterized type instances.

Map<String, List<String>> m =
new HashMap<String, List<String>>();

With static factories, however, the compiler can figure out the type parameters for you. This is known as type inference. For example, suppose that HashMap provided this static factory:

public static <K, V> HashMap<K, V> newInstance() {
return new HashMap<K, V>();
}

Then you could replace the wordy declaration above with this succinct alternative:

Map<String, List<String>> m = HashMap.newInstance();

Disadvantages:
1)    Classes without public or protected constructors cannot be subclassed.
2)    They are not readily distinguishable from other static methods.

They do not stand out in API documentation in the way that constructors do, so it can be difficult to figure out how to instantiate a class that provides static factory methods instead of constructors.

Here are some common names for static factory methods:
valueOf—Returns an instance that has, loosely speaking, the same value as its
parameters. Such static factories are effectively type-conversion methods.
of—A concise alternative to valueOf, popularized by EnumSet (Item 32).
getInstance—Returns an instance that is described by the parameters but
cannot be said to have the same value. In the case of a singleton, getInstance
takes no parameters and returns the sole instance.
newInstance—Like getInstance, except that newInstance guarantees that
each instance returned is distinct from all others.
getType—Like getInstance, but used when the factory method is in a different
class. Type indicates the type of object returned by the factory method.
newType—Like newInstance, but used when the factory method is in a different
class. Type indicates the type of object returned by the factory method.

In summary, static factory methods and public constructors both have their
uses, and it pays to understand their relative merits. Often static factories are preferable,
so avoid the reflex to provide public constructors without first considering
static factories.

Reference: Effective Java 2nd Edition by Joshua Bloch