Effective Java (Second Edition), Item 4, discusses using private constructors to enforce noninstantiability. Here\'s the code sample from the book:
public fi
You can create your own class extending Throwable
, e.g.:
class NoninstantiabilityError extends Throwable
This has the following advantages:
Throwable
it is unlikely that it will be caught by accidentThrowable
it is checked and calling the respective constructor by accident would require catching the exceptionUsage example:
public final class UtilityClass {
private UtilityClass() throws NoninstantiabilityError {
throw new NoninstantiabilityError();
}
...
}
There is an assertion: "I'm asserting that this constructor will never be called". So, indeed, AssertionError
is correct here.
When the code requires the inclusion of the JUnit as a dependency such as within the maven test scope <scope>test</scope>
, then go straight to Assertion.fail()
method and benefit from significant improvement in clarity.
public final class UtilityClass {
private UtilityClass() {
fail("The UtilityClass methods should be accessed statically");
}
}
When outside the test scope, you could use something like the following, which would require a static import to use like above. import static pkg.Error.fail;
public class Error {
private static final Logger LOG = LoggerFactory.getLogger(Error.class);
public static void fail(final String message) {
LOG.error(message);
throw new AssertionError(message);
// or use your preferred exception
// e.g InstantiationException
}
}
Which the following usage.
public class UtilityClassTwo {
private UtilityClassTwo() {
Error.fail("The UtilityClass methods should be accessed statically");
}
}
In its most idiomatic form, they all boil down to this:
public class UtilityClassThree {
private UtilityClassThree() {
assert false : "The UtilityClass methods should be accessed statically";
}
}
One of the built in exceptions, UnsupportedOperationException can be thrown to indicate that 'the requested operation is not supported'.
private Constructor() {
throw new UnsupportedOperationException(
"Do not instantiate this class, use statically.");
}
I like including Bloch's comment:
// Suppress default constructor for noninstantiability
Or better yet putting it in the Error:
private UtilityClass()
{
throw new AssertionError("Suppress default constructor for noninstantiability");
}
A broken assertion means that you've broken a contract specification of your code. So it's the right thing here.
However, as I assume you'll be privately instantiating an instance, it will also call the constructor and cause an error- unless you have another constructor?
What about IllegalAcessError ? :)