Подтвердить что ты не робот

Всегда ли нужно публиковать конструкторы?

Мой первый вопрос -

   class Explain() {
        public Explain() {
      }
   }

Должен ли Constructor объявлять общедоступным?

Что делать, если я создаю конструктор private.

Я всегда видел, что конструкторы неявно public. Итак, почему конструктор private полезен? Или это вообще не полезно. Потому что никто никогда не мог назвать это или никогда не создавать объект (из-за конструктора private)! И это мой второй вопрос.

4b9b3361

Ответ 1

Нет, конструкторы могут быть public, private, protected или default (вообще нет модификатора доступа).

Создание чего-то private не означает, что никто не сможет получить к нему доступ. Это просто означает, что никто за пределами класса не может получить к нему доступ. Поэтому конструктор private тоже полезен.

Одним из использования конструктора private является использование одноэлементных классов. Класс singleton - это тот, который ограничивает количество создания объектов одним. Используя конструктор private, мы можем гарантировать, что за один раз может быть создано не более одного объекта.

Пример -

public class Database {

    private static Database singleObject;
    private int record;
    private String name;

    private Database(String n) {
        name = n;
        record = 0;
    }

    public static synchronized Database getInstance(String n) {
        if (singleObject == null) {
            singleObject = new Database(n);
        }

        return singleObject;
    }

    public void doSomething() {
        System.out.println("Hello StackOverflow.");
    }

    public String getName() {
        return name;
    }
}

Дополнительная информация о модификаторах доступа.

Ответ 2

Да, конструкторы могут иметь какой-либо модификатор/модификатор доступа.

Частные конструкторы полезны для создания классов singleton.

Singleton. Класс singleton - это класс, в котором только один объект может быть создан во время выполнения (за JVM).

Простой пример одноэлементного класса -

class Ex {
    private static Ex instance;
    int a;
    private Ex() {
        a = 10;
    }
    public static Ex getInstance() {
        if(instance == null) {
            instance = new Ex();
        }
        return instance;
    }
}

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

Кроме того, обратите внимание, что это не является потокобезопасным.

Ответ 3

Конструкторы могут быть общедоступными, стандартными или частными, и все зависит от того, что вы хотите с ним делать.

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

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

Более подробную информацию можно найти здесь

Ответ 4

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

Частный конструктор означает: "Я не позволяю кому-либо создавать мой экземпляр, кроме меня". Поэтому обычно вы делаете это, когда вам нравится иметь одноэлементный шаблон.

Ниже приведен класс в JDK, который использует частный конструктор.

public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    // Don't let anyone else instantiate this class
    private Runtime() {
    }
}

Ответ 5

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

Пример

class Alpha {
   static String s = " ";
   protected Alpha() { s += "alpha "; }
 }
 class SubAlpha extends Alpha {
   private SubAlpha() { s += "sub "; }
 }
 public class SubSubAlpha extends Alpha {
   private SubSubAlpha() { s += "subsub "; }
   public static void main(String[] args) {
     new SubSubAlpha();
     System.out.println(s);
   }
 }

Вывод вышеуказанной программы будет

alpha subsub

Ответ 6

Конструкторы могут иметь все виды модификаторов доступа. Использование разных модификаторов доступа в конструкторах отличается.

Вы создаете конструктор public, если вы хотите, чтобы класс был создан из любого места.

Вы создаете конструктор protected, если вы хотите, чтобы класс был наследован и его унаследованные классы были созданы.

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

Ответ 7

Я согласен с предыдущими ответами, что Singleton - хороший пример класса, имеющего частный конструктор. Я бы рекомендовал другую реализацию: потокобезопасный Singleton:

/**
 * Thread safe singleton
 */
public class Singleton {

    private static volatile Singleton instance = null;

    /**
     * Private constructor
     */
    private Singleton() {
    }

    /**
     * Gets the Instance of the Singleton in a thread safe way.
     * @return
     */
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

Использование одноэлементного потока в безопасном потоке поможет вам избежать боли в параллельном коде.

Ответ 8

Конструктор имеет как минимум защищенный или даже закрытый при создании, например, пользовательских классов factory, таких как:

public final class MyFactory {
  private MyFactory(){} // this one prevents instances of your factory
}

public static void doSomething(){} // access that with MyFactory.doSomething

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

Ответ 9

Большинство этих ответов относятся к классу singleton или factory. В другой раз, когда появляется частный конструктор (например), в java.lang.Math class, где все статично, и никто не должен когда-либо звонить конструктор (включая сам класс). Имея частный конструктор, вы запрещаете кому-либо, кроме класса, вызвать конструктор. (Это не мешает кому-либо из класса вызвать конструктор, но затем они нарушают свое собственное правило.)

Ответ 10

Другие отметили, что конструкторы могут иметь модификаторы доступа; еще не упомянутый аспект заключается в том, что модификаторы аспекта на конструкторе управляют двумя очень разными аспектами конструкции, но не позволяют им управлять отдельно:

  • Кому разрешено создавать экземпляры ClassName и какие конструкторы им разрешено использовать.
  • Кому разрешено создавать расширения ClassName и какие конструкторы им разрешено использовать.

Как Java, так и .NET требуют, чтобы ответы на эти два вопроса совпадали; если класс не final (или sealed) и позволяет конструктору использовать внешний код для создания новых экземпляров, тогда внешний код также будет иметь полную свободу использовать тот же самый конструктор для создания производных типов.

Во многих случаях может быть целесообразным, чтобы класс имел только конструкторы package-private (internal), но раскрывал общедоступные методы, которые возвращают новые экземпляры. Такой подход может быть использован, если вы разрабатываете такой тип, как String с нуля; пакет, включающий String, может определять его как абстрактный тип, но включает конкретные производные типы, такие как AsciiString и UCS16String, которые хранят их содержимое как byte[] и Char[] соответственно; методы, возвращающие String, могут затем вернуть одну из производных в зависимости от того, содержат ли строки символы вне диапазона ASCII. Если ни String, ни любые производные типы не выставляют никаких конструкторов вне своего пакета, и все производные типы внутри пакета будут вести себя как строка, как ожидается, будут вести себя, тогда код, который получает ссылку типа String, может ожидать, что он будет вести себя разумно как строка (например, гарантируя, что любые наблюдения за ее значением навсегда останутся верными). Однако использование конструкторов вне пакета позволило бы производным типам вести себя странным и причудливым образом (например, изменять их содержимое после того, как они были проверены и проверены).

С синтаксической точки зрения возможность сказать Fnord foo = new Fnord(123); немного приятнее, чем говорить Fnord foo = Fnord.Create(123);, но класс Fnord, который требует последнего синтаксиса, может значительно улучшить контроль над процессом создания объекта.

Ответ 11

Простым объяснением является отсутствие конструктора в классе, компилятор автоматически создает конструктор по умолчанию.

Конструктор не всегда объявляется общедоступным, он также может быть закрытым, защищенным или по умолчанию.

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