Главная » Java, Советы » Отсутствие экземпляров обеспечивает закрытый конструктор

0

 

Время от времени приходится писать класс, который является всего лишь собранием статических методов и статических полей. Такие классы приобрели дурную репутацию, поскольку отдельные личности неправильно пользуются ими с целью написания процедурных программ с помощью объектно-ориентированных языков. Подобные классы требуют правильного применения. Их можно использ~ать для того, чтобы собирать вместе связанные друг с другом методы обработки простых значений или массивов, как это сделано в библиотеках java.lang.Math и java.util.Arrays, либо чтобы собирать вместе статические методы объектов, которые реализуют определенный интерфейс, как это сделано в j ауа.util.Collections. Можно также собрать Методы в некоем окончательном (fina!) классе вместо того, чтобы заниматься расширением Класса.

Подобные классы утилит (uti!ity c!ass) разрабатываются не для того, чтобы СОздавать для них экземпляры – такой экземпляр был бы абсурдом. Однако если у Класса нет явных конструкторов, компилятор по умолчанию сам создает для него ОТКРытый конструктор (defau!t constructor), не имеющий параметров. Для пользователя этот Конструктор ничем не будет отличаться от любого другого. В опубликованных АРI нередко можно встретить классы, непреднамеренно наделенные способностью порождать экземпляры. 11

Попытки запретить классу создавать экземпляры, объявив его абстрактным, не работают. Такой класс может иметь подкласс, для которого можно’ создавать экземпляры. Более того, это вводит пользователя в заблуждение, заставляя думать, что данный класс был разработан именно для наследования (статья 15). Существует, однако, простая идиома, гарантирующая отсутствие экземпляров. Конструктор по умолчанию создается только тогда, когда у класса нет явных конструкторов, и потому запретить создание экземпляров можно, поместив в класс единственный явный закрытый конструктор:

 

// Класс утилит, не имеющий экэемпляров

public class UtilityClass {

// Подавляет появление конструктора по умолчанию, а заодно и создание экземпляров класса

    private UtilityClass() {

                 // Этот конструктор никогда не будет вызван

 

    }

   // …  // Остальное опущено

}

 

Поскольку явный конструктор заявлен как закрытый (private), за пределами класса он будет недоступен. И если конструктор не вызывается в самом классе, это является гарантией того, что для класса никогда не будет создано никаких экземпляров. Эта идиома несколько алогична, так как конструктор создается здесь именно для того, чтобы им нельзя было пользоваться. Есть смысл поместить в текст про граммы комментарий, который описывает назначение данного конструктора.

Побочным эффектом является то, что данная идиома не позволяет создавать подклассы для этого класса. Явно или неявно, все конструкторы должны вызывать доступный им конструктор суперкласса. Здесь же подкласс лишен доступа к конструктору, к которому можно было бы обратиться.

 

Источник: Джошуа Блох, Java TM Эффективное программирование, Издательство «Лори»

По теме:

  • Комментарии