wake-up-neo.com

Kann ein Konstruktor in Java privat sein?

Kann ein Konstruktor privat sein? Wie ist ein privater Konstruktor nützlich?

203
Rajesh

Ja, ein Konstruktor kann privat sein. Es gibt verschiedene Verwendungen davon. Eine solche Verwendung ist für das Singleton Design Anti-Pattern , das ich von Ihnen abraten würde. Eine andere, legitimere Verwendung besteht in der Delegierung von Konstruktoren. Sie können einen Konstruktor haben, der viele verschiedene Optionen verwendet, die eigentlich ein Implementierungsdetail sind. Sie machen ihn also privat, aber Ihre verbleibenden Konstruktoren delegieren ihn.

Als Beispiel für das Delegieren von Konstruktoren können Sie mit der folgenden Klasse einen Wert und einen Typ speichern. Dies ist jedoch nur für eine Teilmenge von Typen möglich. Daher muss der allgemeine Konstruktor als privat eingestuft werden, um sicherzustellen, dass nur die zulässigen Typen verwendet werden . Der allgemeine private Konstruktor hilft bei der Wiederverwendung von Code.

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;
     }
}

Bearbeiten
Wenn ich diese Antwort von einigen Jahren später betrachte, möchte ich anmerken, dass diese Antwort sowohl unvollständig als auch etwas extrem ist. Singletons sind in der Tat ein Anti-Pattern und sollten im Allgemeinen nach Möglichkeit vermieden werden; Allerdings gibt es neben Singletons viele Verwendungsmöglichkeiten für private Konstruktoren, und meine Antwort nennt nur einen.

Um ein paar weitere Fälle anzugeben, in denen private Konstruktoren verwendet werden:

  1. Um eine nicht wiederholbare Klasse zu erstellen, die nur aus einer Sammlung verwandter statischer Funktionen besteht (dies ist im Grunde ein Singleton, aber wenn sie stateless ist und die statischen Funktionen streng auf die Parameter und nicht auf den Klassenstatus angewendet werden), ist dies kein so vernünftiger Ansatz wie ich früher selbst scheint dies zu vermuten, obwohl die Verwendung einer Schnittstelle, die abhängige Abhängigkeiten enthält, die Wartung der API oft erleichtert, wenn die Implementierung eine größere Anzahl von Abhängigkeiten oder anderen Kontextformen erfordert.

  2. Wenn das Objekt auf verschiedene Weise erstellt werden kann, kann ein privater Konstruktor das Verständnis der verschiedenen Konstruktionsmethoden erleichtern (z. B. welche für Sie new ArrayList(5) oder ArrayList.createWithCapacity(5), ArrayList.createWithContents(5), ArrayList.createWithInitialSize(5) besser lesbar ist). Mit anderen Worten: Mit einem privaten Konstruktor können Sie Factory-Funktionen bereitstellen, deren Namen verständlicher sind. Wenn Sie den Konstruktor als privat kennzeichnen, wird sichergestellt, dass nur die selbstverständlicheren Namen verwendet werden. Dies wird auch häufig mit dem Builder-Muster verwendet. Zum Beispiel:

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

Ich hatte erwartet, dass jemand dies erwähnt hätte (der zweite Punkt), aber es gibt drei Verwendungsmöglichkeiten für private Konstruktoren:

  • um die Instantiierung außerhalb des Objekts zu verhindern, gilt in den folgenden Fällen:

    • singleton
    • fabrikmethode
    • nur statische Methoden (Dienstprogramm) 
    • nur Konstanten Klasse
      .
  • um sublcassing zu verhindern (ausdehnen). Wenn Sie nur einen privaten Konstruktor erstellen, kann keine Klasse Ihre Klasse erweitern, da sie den Konstruktor super() nicht aufrufen kann. Dies ist eine Art Synonym für final

  • Überladene Konstruktoren - aufgrund der Überladung von Methoden und Konstruktoren können einige privat und andere öffentlich sein. Insbesondere wenn eine nicht öffentliche Klasse in Ihren Konstruktoren verwendet wird, können Sie einen öffentlichen Konstruktor erstellen, der eine Instanz dieser Klasse erstellt und diese an einen privaten Konstruktor übergibt.

87
Bozho

Ja, kann es. Ein privater Konstruktor würde existieren, um zu verhindern, dass die Klasse instanziiert wird, oder weil die Konstruktion nur intern erfolgt, z. ein Fabrikmuster. Siehe hier für weitere Informationen.

24
Feanor

Ja.

Auf diese Weise können Sie steuern, wie die Klasse instanziiert wird. Wenn Sie den Konstruktor als privat definieren und dann eine sichtbare Konstruktormethode erstellen, die Instanzen der Klasse zurückgibt, können Sie beispielsweise die Anzahl der Kreationen begrenzen (normalerweise sicherstellen, dass es genau eine Instanz gibt) oder Instanzen oder andere auf die Konstruktion bezogene Aufgaben ausführen .

Wenn Sie new x() tun, wird nie null zurückgegeben. Mit dem Factory-Muster können Sie jedoch null oder sogar verschiedene Untertypen zurückgeben.

Sie können es auch für eine Klasse verwenden, die keine Instanzmitglieder oder Eigenschaften hat, sondern nur statische - wie in einer Utility-Funktionsklasse.

16
lavinio

Wenn alle Ihre Methoden in einer Klasse statisch sind, ist ein privater Konstruktor eine gute Idee.

9
lichenbo

Private Konstruktoren können aus folgenden Gründen in Java definiert werden

  1. Um die Instantiierung der Java-Objekte zu kontrollieren, können Sie keine Instanz eines Objekts erstellen.

  2. Es wird nicht zulassen, dass die Klasse Unterklasse ist

  3. Dies hat einen besonderen Vorteil bei der Implementierung von Singleton Pattern . Private Konstruktoren werden dafür verwendet und steuern die Erstellung der Instanz für die gesamte Anwendung.

  4. wenn Sie möchten, dass eine Klasse mit allen Konstanten definiert wird und deren Instanz nicht mehr erforderlich ist, wird diese Klasse als privater Konstruktor deklariert.

6
gmhk

Ja.

Ein privater Konstruktor wird verwendet, um das Initialisieren von Instanzen zu verhindern, z. B. die endgültige Math-Klasse, die Sie in Java verwenden. Singleton verwendet auch einen privaten Konstruktor

5
ryf9059

Ja. Klasse kann privaten Konstruktor haben. Sogar eine abstrakte Klasse kann einen privaten Konstruktor haben.

Indem wir den Konstruktor als privat definieren, verhindern wir, dass die Klasse instanziiert wird und dass diese Klasse auch Unterklassen enthält.

Hier einige Verwendungsmöglichkeiten des privaten Konstruktors: 

  1. Singleton Design Pattern
  2. Um die Anzahl der Instanzerstellung zu begrenzen
  3. Um einen aussagekräftigen Namen für die Objekterstellung mit der statischen Factory-Methode zu vergeben 
  4. Statische Dienstprogrammklasse oder Konstantenklasse
  5. Um Unterklassen zu verhindern
  6. Builder Design Pattern und damit für unveränderliche Klassen erstellen
4
Abhi Andhariya

Ja, die Klasse kann einen privaten Konstruktor haben. Es ist erforderlich, den Zugriff auf den Konstruktor von anderen Klassen nicht zuzulassen und innerhalb der definierten Klasse zugänglich zu bleiben.

Warum möchten Sie, dass Objekte Ihrer Klasse nur intern erstellt werden? Dies kann aus irgendeinem Grund geschehen, aber ein möglicher Grund ist, dass Sie ein Singleton implementieren möchten. Ein Singleton ist ein Entwurfsmuster, mit dem nur eine Instanz Ihrer Klasse erstellt werden kann. Dies kann mithilfe eines privaten Konstruktors erfolgen.

3
SBTec

Ja, und es wird verwendet, um die Instantiierung zu verhindern und anschließend zu überschreiben. Dies wird am häufigsten in Singleton-Klassen verwendet.

2
Vaishak Suresh

ja, ein Konstruktor kann privat sein. Ein privater Konstruktor verhindert, dass jede andere Klasse ein Beispiel für einen privaten Konstruktor instanziiert 

public class CustomHttpClient {
private static HttpClient customHttpClient;

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

Private Konstruktoren verhindern, dass eine Klasse explizit von Aufrufern instanziiert wird Weitere Informationen finden Sie unter PrivateConstructor

1
GustyWind

Meiner Meinung nach können wir Konstruktor als privat deklarieren, und wir Können die Instanz dieser Klasse in der Unterklasse abrufen, indem Sie die statische Methode in der Klasse verwenden, in der wir den Konstruktor deklarieren und dann das Klassenobjekt zurückgeben. Wir klassifizieren diese Methode von der Unterklasse aus by verwendet classname.method name bcz. Es handelt sich um eine statische Methode, und wir erhalten die Instanz der Klasse, in der wir const deklarieren. 

0
user3391823

Kann ein Konstruktor privat sein? Wie ist ein privater Konstruktor nützlich?

Ja, kann es. Ich halte dies für ein weiteres Beispiel, dass es nützlich ist:

//... 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;
        }
    }
}

In diesem Fall wird verhindert, dass die abstrakte Klasse von anderen abgeleiteten Klassen als ihren statischen inneren Klassen instanziiert wird. Abstrakte Klassen können nicht final sein, aber in diesem Fall macht der private Konstruktor sie für alle Klassen, die keine inneren Klassen sind, effektiv final

0
Werner Erasmus

Die Grundidee hinter einem privaten Konstruktor besteht darin, die Instantiierung einer Klasse von außen durch JVM einzuschränken. Wenn jedoch eine Klasse einen Argumentkonstruktor hat, wird daraus abgeleitet, dass eine Instanz absichtlich instantiiert wird.

0
Phani