Java | How to Enforce Non-Instantiability of a Class?

effective-java-item-4.png

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(){
	        // ....
	 }
}