Java | How to Enforce Non-Instantiability of a Class?
Interfaces and abstract classes are non-instantiable i.e. we can’t directly create instances out of them. Regular classes are instantiable by default, so how to enforce non-instantiability?
“Enforce the singleton property with private constructor or an enum type” ~ Joshua Block’s, Effective Java
Why Do We Need Non-instantiable Classes?
- You may need to have a class that provides static methods and fields e.g.
java.lang.Math
- Such classes should not be instantiated since their static members are accessible without creating an instance.
public final class MyUtility{
public static void doSomething(){
// ....
}
}
How to Enforce Non-instantiability?
No explicit constructor
- Writing a class without an explicit constructor is the first step. However, it is not enough since the compiler will implicitly provide the default constructor.
MyUtility
is still instantiable using the default constructor.
public static void main(String[] args) {
new MyUtility();
}
Not abstract
- Making the class abstract is not enough since abstract class can be extended specially that abstract class is usually designed for inheritance.
public abstract class MyUtility {
public static void doSomething(){
// ....
}
}
class MySubUtility extends MyUtility{}
Include a private constructor
- private constructor will prevent the creation of new instances even if the class is extended.
- One exception is that the private constructor can be called from within the class.
public class MyUtility {
private MyUtility() {}
public static void doSomething(){
// ....
}
}
Throw an Error
- To prevent the calling of the constructor from within the class, throw an error.
public class MyUtility {
private MyUtility() {
throw new AssertionError();
}
public static void doSomething(){
// ....
}
}