Как создать синглтон
Короткий ответ
Синглтон — класс, у которого существует ровно один объект. Самый простой и надёжный способ — enum с одним значением:
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);
}Результат:
dev
trueЛенивое создание
Если объект дорого создавать, вложенный класс-держатель создаст его при первом обращении. JVM гарантирует, что это потокобезопасно:
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);
}Результат:
start
Registry created
trueЗдесь класс объявлен как static, потому что в компактном файле он вложен в неявный класс программы. В отдельном файле Registry.java слово static не нужно.
Частая ошибка
Ленивое создание с проверкой if (instance == null) без синхронизации. Два потока одновременно видят null и создают два объекта. Используйте enum или класс-держатель. И помните: синглтоны усложняют тесты — часто лучше создать один объект в main и передавать его туда, где он нужен.