Implementing the Singleton Pattern in Java
The Singleton pattern guarantees that a class has only one unique instance and supplies a unified global entry point for accessing that instance. It is particularly useful when you need to strict control the number of object instances to save system resources or maintain consistent state.
A valid Singleton implementation must meet three core requirements:
- The class restricts itself to a single instance.
- The class takes full resopnsibility for creating that instance.
- The class provides a public method for the rest of the system to retrieve the instance.
This is typically achieved by making the constructor private to prevent external instantiation and exposing a static method to return the pre-created instance.
Consider a country that can only have one active leader at a time. The following code demonstrates an eager initialization approach:
package com.example.design;
public class NationalLeader {
// Eagerly initialize the instance when the class loads
private static final NationalLeader instance = new NationalLeader();
// Private constructor prevents external instantiation
private NationalLeader() {}
// Global access point
public static NationalLeader getLeader() {
return instance;
}
public void addressCitizens() {
System.out.println("Greetings to all citizens!");
}
}
class Application {
public static void main(String[] args) {
NationalLeader leader1 = NationalLeader.getLeader();
leader1.addressCitizens();
NationalLeader leader2 = NationalLeader.getLeader();
leader2.addressCitizens();
System.out.println("Identity check (same object?): " + (leader1 == leader2));
}
}
Output:
Greetings to all citizens!
Greetings to all citizens!
Identity check (same object?): true
A classic example of this pattern in the Java Development Kit is the Runtime class, which allows accesss to the environment in which the application is running:
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
private Runtime() {}
}