Может ли конструктор в Java быть закрытым? - PullRequest
210 голосов
/ 12 мая 2010

Может ли конструктор быть приватным? Чем полезен приватный конструктор?

Ответы [ 15 ]

144 голосов
/ 12 мая 2010

Да, конструктор может быть приватным. Есть разные варианты использования этого. Одно из таких применений - 1005 *, который я бы советовал вам не использовать. Другое, более законное использование, заключается в делегировании конструкторов; у вас может быть один конструктор, который принимает множество различных опций, что на самом деле является деталью реализации, поэтому вы делаете его закрытым, но тогда оставшиеся конструкторы делегируют его.

В качестве примера делегирования конструкторов, следующий класс позволяет вам сохранять значение и тип, но он позволяет делать это только для подмножества типов, поэтому необходимо сделать общий конструктор частным, чтобы гарантировать, что только разрешенные типы используются. Общий частный конструктор помогает повторно использовать код.

public class MyClass {
     private final String value;
     private final String type;

     public MyClass(int x){
         this(Integer.toString(x), "int");
     }

     public MyClass(boolean x){
         this(Boolean.toString(x), "boolean");
     }

     public String toString(){
         return value;
     }

     public String getType(){
         return type;
     }

     private MyClass(String value, String type){
         this.value = value;
         this.type = type;
     }
}

Редактировать
Глядя на этот ответ спустя несколько лет, я хотел бы отметить, что этот ответ является как неполным, так и несколько экстремальным. Синглтоны действительно являются анти-паттернами, и их следует избегать, где это возможно; однако, помимо синглетонов, существует множество применений частных конструкторов, и мой ответ называет только один.

Чтобы дать еще пару случаев, когда используются частные конструкторы:

  1. Создать нереализуемый класс, который представляет собой просто набор связанных статических функций (это в основном одноэлементный объект, но если он не имеет состояния и статические функции работают строго по параметрам, а не по состоянию класса, это не такой необоснованный подход, как мне показалось бы ранее, хотя использование интерфейса с внедренной зависимостью часто облегчает поддержку API, когда реализация требует большего числа зависимостей или других форм контекста).

  2. Когда существует несколько различных способов создания объекта, закрытый конструктор может облегчить понимание различных способов его создания (например, который более читабелен для вас new ArrayList(5) или ArrayList.createWithCapacity(5), ArrayList.createWithContents(5), ArrayList.createWithInitialSize(5)). Другими словами, приватный конструктор позволяет вам предоставлять фабричные функции, имена которых более понятны, а затем делает конструктор приватным, чтобы люди использовали только более очевидные имена. Это также обычно используется с шаблоном построителя . Например:

    MyClass myVar = MyClass
        .newBuilder()
        .setOption1(option1)
        .setOption2(option2)
        .build();
    
90 голосов
/ 12 мая 2010

Я ожидал, что кто-то упомянул бы это (2-й пункт), но .. есть три варианта использования частных конструкторов:

  • для предотвращения создания экземпляров вне объекта, в следующих случаях:

    • одноточечно
    • фабричный метод
    • класс только для статических методов (утилита)
    • класс только для констант
      .
  • для предотвращения подкласса (расширения). Если вы создаете только приватный конструктор, ни один класс не может расширить ваш класс, потому что он не может вызвать конструктор super(). Это какой-то синоним final

  • перегруженные конструкторы - в результате перегрузки методов и конструкторов некоторые могут быть частными, а некоторые общедоступными. Особенно в том случае, если в ваших конструкторах используется непубличный класс, вы можете создать открытый конструктор, который создает экземпляр этого класса и затем передает его частному конструктору.

24 голосов
/ 12 мая 2010

Да, может. Частный конструктор будет существовать для предотвращения создания экземпляра класса или потому, что конструирование происходит только внутри, например Фабричный образец. См. здесь для получения дополнительной информации.

16 голосов
/ 12 мая 2010

Да.

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

Выполнение new x() никогда не возвращает null, но, используя фабричный шаблон, вы можете вернуть null или даже вернуть разные подтипы.

Вы можете использовать его также для класса, который не имеет элементов или свойств экземпляра, только статические - как в классе служебных функций.

9 голосов
/ 28 июня 2012

Что ж, если все ваши методы в классе являются статическими, тогда закрытым конструктором будет хорошая идея.

6 голосов
/ 12 мая 2010

Частные Конструкторы могут быть отклонены в Java по следующим причинам

  1. Чтобы иметь возможность управлять экземплярами объектов Java, он не позволяет создавать экземпляр объекта.

  2. Он не позволяет классу быть разделенным на подклассы

  3. Это имеет особое преимущество при реализации одноэлементного шаблона . Для него используются частные конструкторы, которые позволяют создавать экземпляр для всего приложения.

  4. когда вы хотите, чтобы класс со всеми определенными константами и больше не требовал его экземпляра, тогда мы объявляем этот класс как частный конструктор.

5 голосов
/ 12 мая 2010

Да.

Закрытый конструктор используется для предотвращения инициализации экземпляра, например, финальный класс Math, который вы используете в Java. Синглтон также использует приватный конструктор

4 голосов
/ 09 июля 2017

Да. Класс может иметь приватный конструктор. Даже абстрактный класс может иметь приватный конструктор.

Делая конструктор закрытым, мы предотвращаем создание экземпляров класса и его подклассы.

Вот некоторые примеры использования частного конструктора:

  1. Шаблон проектирования Singleton
  2. Чтобы ограничить количество созданных экземпляров
  3. Чтобы дать осмысленное имя для создания объекта с использованием статического метода фабрики
  4. Статический класс полезности или класс констант
  5. Для предотвращения подклассов
  6. Шаблон проектирования Builder и, следовательно, для создание неизменяемых классов
3 голосов
/ 07 июня 2012

Да, класс может иметь приватный конструктор. Это необходимо для того, чтобы запретить доступ к конструктору из других классов и оставить его доступным в пределах определенного класса.

Почему вы хотите, чтобы объекты вашего класса создавались только внутри? Это может быть сделано по любой причине, но одна из возможных причин заключается в том, что вы хотите реализовать синглтон. Singleton - это шаблон проектирования, который позволяет создавать только один экземпляр вашего класса, и это можно сделать с помощью частного конструктора.

2 голосов
/ 05 октября 2013

Да, конструктор может быть приватным. Закрытый конструктор не позволяет любому другому классу создавать пример закрытого конструктора

public class CustomHttpClient {
private static HttpClient customHttpClient;

/** A private Constructor prevents any other class from instantiating. */
private CustomHttpClient() {
}}
...