When private
keyword is assigned to a method, then that method cannot be access by other outside class, this way we can add security to those methods. Since Constructors are also like methods in Java, we can make the Constructor as private. Object for the class can only be created internally within the class, no outside class can create object for this class if constructor is private. Using this we can restrict the caller from creating objects.
Some of the uses of private constructors:
- Singleton Design Pattern
- Limit number of instance creation
- Static Utility Class
- Prevent Subclassing
- Builder Design Pattern
Singleton Design Pattern
A class is said to be singleton if it limits the number of objects of that class to one. We can’t have more than a single object for such classes. Singleton classes are employed extensively in concepts like Networking and Database Connectivity.
// Singleton pattern using private constructors. class SingletonExample { static SingletonExample instance = null; public int x = 10; // private constructor can't be accessed outside the class private SingletonExample() { } // Factory method to provide the users with instances static public SingletonExample getInstance() { if (instance == null) { instance = new SingletonExample(); } return instance; } } class Main{ public static void main(String args[]){ SingletonExample a = SingletonExample.getInstance(); a.x = a.x + 10; } }
Limit number of instance creation
By making constructor private and then creating a visible constructor method, we can limit the number of instance creations (like we do in singleton design pattern).
class ObjectCreation { // Count of alive instances in JVM public static int objCount = 0; // private constructor private ObjectCreation(){ objCount++; System.out.println("instance " + objCount + " created"); } // static factory method to return ObjectCreation instance public static synchronized ObjectCreation getLimInstance() { if(objCount < 3 ){ return new ObjectCreation(); } return null; } // Decreases the objCount static variable when JVM runs garbage collection @Override public void finalize() { System.out.println("Instance destroyed"); objCount--; } } } public class LimitObjectCreationTest { public static void main(String[] args) { ObjectCreation obj; int i=1; while(i<=20) { obj = ObjectCreation.getLimInstance(); i++; } } }
Static Utility Class
Usefull for scenario when you have a class full of utility functions where instantiating an instance of it makes no semantic sense. Best way to deal with utility class
- Declare class as
final
, so that no other class inherit it. - Declare its constructor private (no instance creation)
- Provide public static utility methods
// Final class example // To avoid extending; classes and methods may be marked as final. public final class A { // Final method public final void someMethod() { //code } }
JDK implementation of Utility classes are
- java.util.Arrays
- java.lang.Math
Prevent Subclassing
We can prevent sublcassing (extending) if we create only a private constructor, no class can extend your class, because it can’t call the super() constructor.
class A { // Private constructor private A() { } } // Compiler will give error class B extends A { }
Builder Design Pattern
Private constructors are also used in Builder Design Pattern and thus creating Immutable classes.