it-roy-ru.com

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

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

203
Rajesh

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

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

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. Чтобы создать нереализуемый класс, который является просто набором связанных статических функций (это в основном одноэлементный объект, но если он не имеет состояния и статические функции работают строго по параметрам, а не по состоянию класса, это не такой необоснованный подход, как мой раннее self, казалось бы, предполагает, хотя использование интерфейса с внедренной зависимостью часто облегчает поддержку API, когда реализация требует большего числа зависимостей или других форм контекста).

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

    MyClass myVar = MyClass
        .newBuilder()
        .setOption1(option1)
        .setOption2(option2)
        .build();
    
143
Michael Aaron Safyan

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

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

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

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

87
Bozho

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

24
Feanor

Да.

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

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

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

16
lavinio

Хорошо, если все ваши методы в классе являются статическими, тогда хороший конструктор - хорошая идея.

9
lichenbo

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

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

  2. Это не позволит классу быть в подклассе

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

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

6
gmhk

Да.

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

5
ryf9059

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

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

Вот некоторые из применений частного конструктора: 

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

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

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

3
SBTec

Да, и он используется для предотвращения создания экземпляров и последующего переопределения. Это чаще всего используется в синглтон-классах.

2
Vaishak Suresh

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

public class CustomHttpClient {
private static HttpClient customHttpClient;

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

Закрытые конструкторы предотвращают явное создание экземпляров класса классами Смотрите дополнительную информацию на PrivateConstructor

1
GustyWind

По моему мнению, мы можем объявить конструктор как приватный, а также Можем получить экземпляр этого класса в подклассе, используя статический метод в классе, в котором мы объявляем конструктор, а затем возвращаем объект класса. мы классифицируем этот метод из подклассаby, используя classname.method name bcz, это статический метод, и мы получим экземпляр класса, в котором мы объявили const. 

0
user3391823

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

Да, оно может. Я считаю, что это еще один пример того, как это полезно:

//... ErrorType.Java
public enum ErrorType {
    X,
    Y,
    Z
}

//... ErrorTypeException.Java
import Java.util.*;
import Java.lang.*;
import Java.io.*;

//Translates ErrorTypes only
abstract public class ErrorTypeException extends Exception {
    private ErrorTypeException(){}

    //I don't want to expose thse
    static private class Xx extends ErrorTypeException {}
    static private class Yx extends ErrorTypeException {}
    static private class Zx extends ErrorTypeException {}

    // Want translation without exposing underlying type
    public static Exception from(ErrorType errorType) {
        switch (errorType) {
            case X:
                return new Xx();    
            case Y:
                return new Yx();
            default:
                return new Zx();
        }
    }

    // Want to get hold of class without exposing underlying type
    public static Class<? extends ErrorTypeException> toExceptionClass(ErrorType errorType) {
        switch (errorType) {
            case X:
                return Xx.class;    
            case Y:
                return Yx.class;
            default:
                return Zx.class;
        }
    }
}

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

0
Werner Erasmus

Основная идея создания частного конструктора состоит в том, чтобы ограничить создание экземпляра класса извне JVM, но если класс имеет конструктор аргумента, то это означает, что он намеренно создается.

0
Phani