A private constructor in Java is a constructor that cannot be accessed outside the class. It is mainly used to restrict object creation and enforce certain design patterns.
1. When to Use a Private Constructor?
Use Case | Why Use a Private Constructor? |
---|---|
Singleton Pattern | Ensures only one instance of a class is created. |
Utility Classes (Math , Collections ) | Prevents instantiation of classes that only contain static methods. |
Factory Methods | Controls object creation through static methods instead of constructors. |
Immutable Classes | Restricts modification by preventing direct object creation. |
2. Example 1: Singleton Pattern (Restricting Multiple Instances)
A singleton ensures that only one instance of a class exists.
✅ Example: Singleton Using a Private Constructor
class Singleton {
private static Singleton instance;
// Private constructor prevents external instantiation
private Singleton() {
System.out.println("Singleton Instance Created");
}
// Public method to return the single instance
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // Create instance if not created
}
return instance;
}
}
public class SingletonExample {
public static void main(String[] args) {
Singleton obj1 = Singleton.getInstance(); // Calls private constructor
Singleton obj2 = Singleton.getInstance(); // Reuses same instance
System.out.println(obj1 == obj2); // true (Same instance)
}
}
✅ Output:
Singleton Instance Created
true
📌 Key Takeaways:
new Singleton();
is not allowed outside the class.getInstance()
ensures only one instance is created.
3. Example 2: Utility Class (Preventing Object Creation)
Utility classes like Math
and Collections
contain only static methods and should never be instantiated.
✅ Example: Utility Class with a Private Constructor
class MathUtils {
private MathUtils() { // Prevents instantiation
throw new UnsupportedOperationException("Cannot instantiate MathUtils");
}
public static int square(int x) {
return x * x;
}
}
public class UtilityClassExample {
public static void main(String[] args) {
// MathUtils obj = new MathUtils(); // ❌ Error: Constructor is private
System.out.println(MathUtils.square(5)); // ✅ Works fine
}
}
✅ Output:
25
📌 Key Takeaways:
- Only static methods are accessible.
- The class cannot be instantiated.
4. Example 3: Factory Method Pattern (Controlled Object Creation)
A factory method controls object creation based on conditions.
✅ Example: Factory Pattern Using a Private Constructor
class Car {
private String model;
// Private constructor
private Car(String model) {
this.model = model;
}
// Factory method for object creation
public static Car createCar(String type) {
if (type.equals("Sedan")) {
return new Car("Toyota Camry");
} else if (type.equals("SUV")) {
return new Car("Honda CR-V");
}
return null;
}
public void display() {
System.out.println("Car Model: " + model);
}
}
public class FactoryPatternExample {
public static void main(String[] args) {
Car sedan = Car.createCar("Sedan");
Car suv = Car.createCar("SUV");
sedan.display(); // Car Model: Toyota Camry
suv.display(); // Car Model: Honda CR-V
}
}
✅ Output:
Car Model: Toyota Camry
Car Model: Honda CR-V
📌 Key Takeaways:
- Clients cannot create objects directly (
new Car("Toyota")
is not possible). - Object creation is centralized and controlled using
createCar()
.
5. Example 4: Preventing Subclassing (Making a Class Final)
A final class with a private constructor ensures that it cannot be extended or instantiated.
✅ Example: Preventing Subclassing
final class Constants {
public static final double PI = 3.14159;
// Private constructor prevents object creation
private Constants() {}
}
public class PreventSubclassingExample {
public static void main(String[] args) {
// Constants obj = new Constants(); // ❌ Error: Constructor is private
System.out.println(Constants.PI); // ✅ Works fine
}
}
✅ Output:
3.14159
📌 Key Takeaways:
final
+private constructor
ensures no subclassing or instantiation.- Used for constants and global variables.
6. Summary of Private Constructor Uses
Use Case | Why Use a Private Constructor? | Example |
---|---|---|
Singleton Pattern | Restricts instantiation to only one object. | Logger.getInstance() |
Utility Class | Prevents instantiation, only allows static methods. | Math , Collections |
Factory Method Pattern | Controls object creation logic within the class. | Car.createCar("SUV") |
Prevent Subclassing | Prevents inheritance & instantiation. | final class Constants { private Constants() {} } |
7. Conclusion
✅ A private constructor is used to control object creation and enforce design patterns.
✅ It prevents direct instantiation from outside the class.
✅ Common use cases include Singleton, Utility classes, Factory Methods, and preventing subclassing.