Есть несколько вещей, чтобы объяснить о синглонах и идиоматике инициализации по требованию. Здесь мы идем:
1) Модификатор доступа:
Обычно вы не можете получить доступ к полям и методам в другом классе, если они являются частными. Они должны, по крайней мере, быть приватными пакетами (без модификатора, если есть), если класс доступа находится в одном пакете. Таким образом, правильный способ его реализации, будет:
public class Singleton {
...
private static class LazyHolder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
Однако JLS 6.6.1 объясняет:
В противном случае, если член или конструктор объявлен частным, то доступ разрешается тогда и только тогда, когда он происходит в теле класса верхнего уровня (§7.6) , которое включает объявление члена или конструктора.
Это означает, что объявление поля INSTANCE
приватных все еще позволяет доступ из внутри верхнего класса уровня Singleton
. Но компилятор должен сделать некоторые трюки, чтобы обойти частный модификатор: он вставляет частные методы пакета для получения и установки такого поля.
На самом деле, это не имеет значения, какой модификатор вы на нем размещаете. Если он является общедоступным, он по-прежнему не может быть доступен из других классов, кроме Singleton
. Однако ... Я думаю, что доступ к пакету является лучшим. Публикация не имеет смысла. Заставляя его частным образом заставить компилятор делать некоторые трюки. Составление частного пакета отражает то, что у вас есть: доступ к члену класса из другого класса.
2) Как реализовать синглтон:
Если вы когда-либо рассмотреть вопрос о сериализации, реализация синглтон будет получить немного сложнее. Джошу Блох написал большой раздел в своей книге «Эффективная Ява» о внедрении синглонов. В конце концов, он пришел к выводу, что для этого просто используется перечисление, поскольку спецификация enum Java предоставляет все харектеристики, которые необходимы в отношении одиночных чисел. Конечно, это больше не использует идиому.
3) Принимая во внимание дизайн:
В большинстве проектных решений, одиночек не имеют места больше. Фактически, это может указывать на проблему с дизайном, если вы должны разместить синглтон в своей программе. Имейте в виду: Singletons предоставляют глобальный acess механизм для некоторых данных или услуг. И это не ООП.
Объявление поля как ** частного ** позволит компилятору вставить ** пакет частных ** методов, правильно? –
Да и нет. Компилятор должен обеспечить, чтобы ни одно частное поле не получало доступ из-за пределов класса. Но он также должен рассмотреть JLS (я цитировал). Итак, трюк заключается в том, чтобы автоматически добавлять частные методы пакета, к которым теперь можно получить доступ извне класса. Эти методы помещаются во внутренний класс, но только в случае необходимости, то есть, если есть действительно доступ, как в этом примере. Кроме того, все прямые обращения к этому частному полю обмениваются вызовами этих методов. – Seelenvirtuose
@Seelenvirtuose, какие проблемы могут возникнуть, если LazyHolder не делает INSTANCE окончательным – masT