Encodera

Thanks for reading!

Donate to the site — we work hard for you.

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
true

Lazy 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
true

The 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.

Functions used in this recipe

  • enum — Declares an enum — a type with a fixed set of values.
  • static — Makes a field or method belong to the class itself rather than to each object.
  • final — Forbids reassigning a variable, overriding a method or extending a class.

Thanks for reading!

Donate to the site — we work hard for you.