Éviter d'instancier une classe en java
Récemment j'ai été confronté à une question : Comment éviter D'instancier une classe Java?
Cependant, j'ai répondu en disant:
Si vous ne voulez pas instancier une classe, utilisez "abstrait" modificateur. Ex: javax.servlet.HttpServlet, est déclaré abstrait (bien qu'aucune de ses méthodes ne soit abstraite) pour éviter l'instanciation.
Déclarer un non argument constructeur privé.
maintenant ma question Est a) existe-t-il d'autres moyens? b) pourquoi quelqu'un ne veut-il pas instancier une classe? - après avoir cherché dans SO, j'ai appris à connaître de que les classes Util peuvent être faites pour ne pas instancier. Tous les autres lieux où nous ne voulons pas instancier une classe en POO?
5 réponses
Quatre raisons viennent à l'esprit:
- pour permettre l'instanciation des sous-classes mais pas du parent;
- Pour interdire direct instanciation et à la place Fournir une méthode d'usine pour retourner et si nécessaire créer des instances;
- parce que toutes les instances sont prédéfinies (p. ex. convient dans un jeu de cartes) bien que depuis Java 5, les enums de typesafe sont recommandés à la place; et
- La classe n'est pas vraiment une classe. C'est juste un support pour constantes statiques et/ou des méthodes.
comme exemple de (2), Vous pouvez vouloir créer des objets canoniques. Par exemple, les combinaisons de couleurs RVB. Vous ne voulez pas créer plus d'une instance d'un combo RGB alors faites ceci:
public class MyColor {
private final int red, green, blue;
private MyColor(int red, int green, int blue) {
this.red = red;
this.green = green;
this.blue = blue;
}
public static MyColor getInstance(int red, int green, int blue) {
// if combo already exists, return it, otherwise create new instance
}
}
Remarque: non non-arg constructeur est nécessaire parce qu'un autre constructeur est défini de façon explicite.
Pas vraiment une réponse à votre question, mais juste une remarque:
lorsque vous créez un constructeur privé no-arg pour empêcher l'instanciation de vos classes d'Utilités, vous devriez demander au constructeur de lancer une exception (par exemple Unsupportedoperdoperationexception). C'est parce que vous pouvez effectivement accéder aux membres privés (y compris les constructeurs) par la réflexion. Notez que si vous le faites, vous devez l'accompagner d'un commentaire, parce que c'est un peu contre-intuitive qui vous définir un constructeur de prévenir une classe d'être instancié.
rendre la classe utilitaire abstraite n'est pas une bonne idée car cela fait ressembler la classe à ce qu'elle est censée être étendue, et de plus vous pouvez étendre la classe et ainsi l'instancier.
parfois vous voulez seulement éviter que d'autres instancient vos objets, afin d'avoir le contrôle total sur toutes les instances existantes. Un exemple est l' le pattern singleton.
je pense que la raison la plus commune pour ne pas vouloir instancier une classe est quand vous avez affaire à une classe statique, et donc à ses méthodes statiques. Vous ne voulez pas que quelqu'un essaie d'instancier cette classe. De même, lorsque vous avez affaire à des classes D'usine ou dans certains cas, de nombreuses classes singleton cachent leur constructeur pour ne pas être instanciées de la manière normale.
une autre façon de rendre une classe non-instantiable serait de la déclarer comme une classe intérieure privée, et de ne pas fournir de moyen de l'instancier dans la classe environnante. Mais ceci est (IMO) assez inutile.
Vous voulez qu'une classe non-instanciable si elle n'a pas de sens pour l'instancier. Vous faites généralement cela si la classe est vraiment juste un ensemble de méthodes d'aide (statiques), ou si la classe est "incomplète". L'incomplétude peut être syntaxiquement évident (c'est à dire abstrait méthodes), mais il ya d'autres types d'incomplétude. Par exemple, vous pouvez fournir des implémentations par défaut pour toutes les méthodes, et exiger qu'une ou plusieurs d'entre elles soient dépassées pour que la classe puisse faire quelque chose d'utile.
une autre raison pour rendre une classe non-instantiable (ou du moins, pas directement instantiable) est si votre application doit contrôler l'instantiation. Par exemple, le java.util.regex.La classe Pattern ne peut pas être instanciée directement de sorte que le JRE peut (pourrait) maintenir un cache de regexes pré-compilés.