web-dev-qa-db-fra.com

Un constructeur en Java peut-il être privé?

Un constructeur peut-il être privé? Comment un constructeur privé est-il utile?

203
Rajesh

Oui, un constructeur peut être privé. Il y a différentes utilisations de cela. Une telle utilisation est pour le singleton anti-motif de conception , que je vous déconseille d'utiliser. Une autre utilisation, plus légitime, consiste à déléguer des constructeurs; vous pouvez avoir un constructeur qui prend beaucoup d'options différentes, qui est vraiment un détail d'implémentation. Vous le rendez donc privé, mais vos constructeurs restants le délèguent.

En tant qu'exemple de délégation de constructeurs, la classe suivante vous permet d'enregistrer une valeur et un type, mais uniquement avec un sous-ensemble de types. Il est donc nécessaire de rendre privé le constructeur général pour que seuls les types autorisés soient utilisés. . Le constructeur privé commun facilite la réutilisation du 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;
     }
}

Modifier
En regardant cette réponse de plusieurs années plus tard, je voudrais noter que cette réponse est à la fois incomplète et aussi un peu extrême. Les singletons sont en effet un anti-modèle et devraient généralement être évités autant que possible; cependant, outre les singletons, les constructeurs privés ont de nombreuses utilisations, et ma réponse n'en nomme qu'un.

Pour donner quelques cas supplémentaires où des constructeurs privés sont utilisés:

  1. Pour créer une classe non instanciable qui est simplement un ensemble de fonctions statiques connexes (il s’agit d’un singleton, mais si elle est sans état et que les fonctions statiques fonctionnent strictement sur les paramètres plutôt que sur l’état de la classe, cette approche n’est pas aussi déraisonnable que la mienne. Il semblerait que ce soit le cas auparavant, bien que l'utilisation d'une interface de dépendance injectée facilite souvent la maintenance de l'API lorsque l'implémentation nécessite un plus grand nombre de dépendances ou d'autres formes de contexte).

  2. Lorsqu'il existe plusieurs manières différentes de créer l'objet, un constructeur privé peut faciliter la compréhension des différentes façons de le construire (par exemple, ce qui est plus lisible pour vous new ArrayList(5) ou ArrayList.createWithCapacity(5), ArrayList.createWithContents(5), ArrayList.createWithInitialSize(5)). En d'autres termes, un constructeur privé vous permet de fournir des fonctions d'usine dont les noms sont plus compréhensibles, puis de le rendre privé garantit que les utilisateurs n'utilisent que les noms les plus évidents. Ceci est également couramment utilisé avec le modèle de générateur . Par exemple:

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

Je m'attendais à ce que quelqu'un l'ait mentionné (le deuxième point), mais .. il y a trois utilisations des constructeurs privés:

  • pour empêcher l'instanciation en dehors de l'objet, dans les cas suivants:

    • singleton
    • méthode d'usine
    • classe statique (utilitaire) uniquement 
    • classe des constantes seulement
      .
  • pour éviter les sous-classes. Si vous ne créez qu'un constructeur privé, aucune classe ne peut étendre votre classe, car elle ne peut pas appeler le constructeur super(). C'est une sorte de synonyme pour final

  • constructeurs surchargés - à la suite de méthodes et de constructeurs surchargés, certains peuvent être privés et d'autres publics. Surtout dans le cas où vous utilisez une classe non publique dans vos constructeurs, vous pouvez créer un constructeur public qui crée une instance de cette classe puis la passe à un constructeur privé.

87
Bozho

Oui il peut. Un constructeur privé existe pour empêcher l’instanciation de la classe ou parce que la construction n’est effectuée qu’en interne, par exemple un modèle d'usine. Voir ici pour plus d'informations.

24
Feanor

Oui.

Cela vous permet de contrôler la manière dont la classe est instanciée. Si vous rendez le constructeur privé, puis créez une méthode de constructeur visible qui renvoie des instances de la classe, vous pouvez, par exemple, limiter le nombre de créations (en général, garantir qu'il n'y a qu'une seule instance), ou recycler des instances ou d'autres tâches liées à la construction. .

Faire new x() ne retourne jamais null, mais en utilisant le modèle d'usine, vous pouvez renvoyer null ou même renvoyer différents sous-types.

Vous pouvez également l'utiliser pour une classe qui n'a pas de membres d'instance ni de propriétés, mais uniquement des propriétés statiques - comme dans une classe de fonction utilitaire.

16
lavinio

Eh bien, si toutes vos méthodes d'une classe sont statiques, un constructeur privé est une bonne idée.

9
lichenbo

Les constructeurs privés peuvent être définis en Java pour les raisons suivantes

  1. Pour avoir le contrôle sur l'instanciation des objets Java, cela ne vous permettra pas de créer une instance d'un objet.

  2. Cela n'autorisera pas le sous-classement de la classe

  3. Cela présente un avantage particulier lors de l’implémentation de singleton Pattern , les convertisseurs privés sont utilisés pour cela et ont un contrôle sur la création de l’instance pour toute l’application.

  4. lorsque vous souhaitez avoir une classe avec toutes les constantes définies et ne nécessitant plus son instance, nous déclarons cette classe en tant que constructeur privé.

6
gmhk

Oui.

Un constructeur privé est utilisé pour empêcher l'initialisation d'instance, telle que la classe Math final que vous utilisez en Java. Singleton utilise également un constructeur privé

5
ryf9059

Oui. La classe peut avoir un constructeur privé. Même la classe abstraite peut avoir un constructeur privé.

En rendant le constructeur privé, nous empêchons l'instanciation de la classe ainsi que son sous-classement.

Voici quelques-unes des utilisations du constructeur privé: 

  1. Singleton Design Pattern
  2. Limiter le nombre de création d'instances
  3. Donner un nom significatif à la création d'objet à l'aide de la méthode fabrique statique
  4. Classe d'utilité statique ou classe constante
  5. Pour éviter le sous-classement
  6. Modèle de conception de constructeur et donc pour créer des classes immuables
4
Abhi Andhariya

Oui, la classe peut avoir un constructeur privé. Il est nécessaire d'empêcher l'accès au constructeur depuis d'autres classes et de le maintenir accessible dans une classe définie.

Pourquoi voudriez-vous que les objets de votre classe ne soient créés qu'en interne? Cela peut être fait pour n'importe quelle raison, mais l'une des raisons possibles est que vous souhaitez implémenter un singleton. Un singleton est un modèle de conception qui ne permet de créer qu'une seule instance de votre classe. Pour ce faire, utilisez un constructeur privé.

3
SBTec

Oui, il est utilisé pour empêcher l’instanciation et, par la suite, la neutralisation. Ceci est le plus souvent utilisé dans les classes singleton.

2
Vaishak Suresh

oui un constructeur peut être privé. Un constructeur privé empêche toute autre classe d'instancier un exemple de constructeur privé 

public class CustomHttpClient {
private static HttpClient customHttpClient;

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

Les constructeurs privés empêchent une instance d'être explicitement instanciée par les appelants Voir plus d'informations sur PrivateConstructor

1
GustyWind

Selon moi, nous pouvons déclarer le constructeur en tant que particulier et nous pouvons également obtenir l'instance de cette classe dans la sous-classe en utilisant une méthode statique dans la classe dans laquelle nous déclarons le constructeur, puis renvoyons un objet de classe. nous classons cette méthode dans la sous-classeby en utilisant classname.method nom bcz, il s'agit d'une méthode statique et nous obtiendrons l'instance de la classe dans laquelle nous déclarons const. 

0
user3391823

Un constructeur peut-il être privé? Comment un constructeur privé est-il utile?

Oui il peut. Je considère ceci comme un autre exemple utile:

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

Dans le cas ci-dessus, cela empêche la classe abstraite d'être instanciée par une classe dérivée autre que ses classes internes statiques. Les classes abstraites ne peuvent pas être finales, mais dans ce cas le constructeur privé le rend effectivement final à toutes les classes qui ne sont pas des classes internes

0
Werner Erasmus

L'idée de base derrière un constructeur privé est de restreindre l'instanciation d'une classe de l'extérieur par la machine virtuelle Java, mais si une classe ayant un constructeur d'arguments, il en déduit qu'il s'agit d'une instanciation intentionnelle.

0
Phani