How to create a singleton
Short answer
A singleton is a class that has exactly one object. The simplest and most reliable way is an enum with a single value:
enum Config {
INSTANCE;
private final Map<String, String> values = new HashMap<>(Map.of("mode", "dev"));
String get(String key) {
return values.get(key);
}
}
void main() {
IO.println(Config.INSTANCE.get("mode"));
IO.println(Config.INSTANCE == Config.INSTANCE);
}Output:
dev
trueLazy creation
If the object is expensive to create, a nested holder class creates it on first access. The JVM guarantees this is thread-safe:
static class Registry {
private Registry() {
IO.println("Registry created");
}
private static class Holder {
static final Registry INSTANCE = new Registry();
}
static Registry getInstance() {
return Holder.INSTANCE;
}
}
void main() {
IO.println("start");
Registry a = Registry.getInstance();
Registry b = Registry.getInstance();
IO.println(a == b);
}Output:
start
Registry created
trueThe class is declared static here because in a compact file it is nested inside the program's implicit class. In a separate Registry.java file you do not need static.
Common mistake
Lazy creation with an if (instance == null) check and no synchronization. Two threads see null at the same time and create two objects. Use an enum or a holder class. And remember: singletons make testing harder — often it is better to create one object in main and pass it where it is needed.