Sometimes,
we want to write a class that is just a grouping of static methods and static
fields. They can be used to group related methods on primitive values or arrays,
in the manner of java.lang.Math or java.util.Arrays. These classes are known as Utility classes.
Utility
classes can also be
used to group static methods, including factories, for objects that implement
some interface, in the manner of java.util.Collections.
Such
utility classes were not designed to be instantiated: an instance would be nonsensical.
In the absence of explicit constructors, however, the compiler provides a
public, parameterless default constructor. To a user, this constructor is indistinguishable
from any other. It is not uncommon to see unintentionally instantiable classes
in published APIs.
Attempting
to enforce noninstantiability by making a class abstract does not work. The
class can be subclassed and the subclass instantiated. Furthermore, it misleads
the user into thinking the class was designed for inheritance.
There
is, however, a simple idiom to ensure noninstantiability. A default constructor
is generated only if a class contains no explicit constructors, so a class can
be made noninstantiable by including a private constructor:
// Noninstantiable utility
class
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
// Remainder omitted
}
Because
the explicit constructor is private, it is inaccessible outside the class. The
AssertionError isn’t strictly required, but it provides insurance in case the constructor
is accidentally invoked from within the class. It guarantees the class will
never be instantiated under any circumstances. This idiom is mildly counterintuitive
because the constructor is provided expressly so that it cannot be invoked. It
is therefore wise to include a comment, as shown earlier.
As
a side effect, this idiom also prevents the class from being subclassed. All constructors
must invoke a superclass constructor, explicitly or implicitly, and a subclass
would have no accessible superclass constructor to invoke.