201 votes

Est-ce une bonne pratique de faire en sorte que le constructeur lève une exception?

Est-ce une bonne pratique de faire en sorte que le constructeur lève une exception? Par exemple, j'ai une classe Person et j'ai age comme attribut unique. Maintenant, je fournis la classe comme

 class Person{
  int age;
  Person(int age) throws Exception{
   if (age<0)
       throw new Exception("invalid age");
   this.age = age;
  }

  public void setAge(int age) throws Exception{
  if (age<0)
       throw new Exception("invalid age");
   this.age = age;
  }
}
 

211voto

Stephen C Points 255558

De lever des exceptions dans un constructeur n'est pas une mauvaise pratique.

Toutefois déclarer explicitement ou en les jetant java.lang.Exception est presque toujours une mauvaise pratique.

Vous devez choisir une classe d'exception qui correspond à l'état exceptionnel, qui a eu lieu. Si vous jetez Exception il est difficile pour l'appelant pour séparer cette exception à partir de n'importe quel nombre d'autres déclarées et non déclarées exceptions. Cela rend la récupération d'erreur difficile, et si l'appelant choisit de propager l'Exception, le problème des écarts de taux.


Quelqu'un a suggéré d'utiliser assert pour la vérification des arguments. Le problème, c'est que la vérification de l' assert des assertions peut être activé et désactivé via une machine virtuelle java en ligne de commande réglage. En utilisant des affirmations de vérification interne d'invariants est OK, mais les utiliser pour mettre en œuvre la vérification argument qui est spécifié dans votre javadoc n'est pas une bonne idée ... parce que cela signifie que votre méthode ne pourra appliquer strictement la spécification lors de l'affirmation de contrôle est activé.

Le deuxième problème avec assert , c'est que si une assertion échoue, alors AssertionError sera levée, et a reçu la sagesse, c'est que c'est une mauvaise idée d'essayer de l'attraper Error et l'un de ses sous-types.

15voto

Spam Suppper Points 21

Vous n'avez pas besoin de jeter un checked exception. C'est un bug dans le contrôle du programme, de sorte vous veux jeter un décoché exception. Utilisez l'une des décoché exceptions déjà prévues par le langage Java, comme IllegalArgumentException, IllegalStateException ou NullPointerException.

Vous pouvez aussi vous voulez vous débarrasser de l'incubateur. Vous avez déjà prévu un moyen pour initier age par le constructeur. Est-il besoin d'être mis à jour une fois instancié? Si non, passez le setter. Une bonne règle, ne pas rendre les choses plus que nécessaire. Démarrer avec le privé, ou par défaut, et de sécuriser vos données avec final. Maintenant tout le monde sait qu' Person a été bien construit, et est immuable. Il peut être utilisé avec confiance.

Le plus probable c'est ce que vous avez vraiment besoin de:

class Person { 

  private final int age;   

  Person(int age) {    

    if (age < 0) 
       throw new IllegalArgumentException("age less than zero: " + age); 

    this.age = age;   
  }

  // setter removed

7voto

ashays Points 493

Je ne l'ai jamais considéré comme une mauvaise pratique de lancer une exception dans le constructeur. Lorsque la classe est conçue, vous avez une certaine idée de ce que la structure de cette classe devrait être. Si quelqu'un a une idée différente et tente d'exécuter cette idée, alors vous devriez erreur en conséquence, donnant à l'utilisateur un retour sur ce qu'est l'erreur. Dans votre cas, vous pouvez envisager quelque chose comme

if (age < 0) throw new NegativeAgeException("The person you attempted " +
                       "to construct must be given a positive age.");

NegativeAgeException est une classe d'exception que vous avez construit vous-même, peut-être étendre une autre exception comme IndexOutOfBoundsException ou quelque chose de similaire.

Les Assertions ne sont pas exactement semblent être la voie à suivre, car vous n'êtes pas d'essayer de découvrir des bugs dans votre code. Je voudrais dire en terminant une exception est absolument la bonne chose à faire ici.

4voto

TofuBeer Points 32441

C'est une mauvaise pratique de lancer Exception, car cela nécessite que toute personne appelant votre constructeur attrape Exception, ce qui est une mauvaise pratique.

C'est une bonne idée de demander à un constructeur (ou à une méthode) de lancer une exception, généralement IllegalArgumentException, qui n'est pas cochée, le compilateur ne vous oblige donc pas à l'attraper.

Vous devez lancer les exceptions vérifiées (les éléments qui vont de Exception, mais pas RuntimeException) si vous voulez que l'appelant le détecte.

3voto

klyd Points 108

À mon avis c'est une bonne pratique: sur le plan conceptuel son une autre couche de protection contre le mal formé des objets.

En plus d'autres langages tels que C#/.Net 4.0 ont ajouté des fonctionnalités: Code de Contrats à le faire -- vérifier les paramètres d'entrée et de lancer des exceptions/avertissements lorsque les paramètres sont en dehors de toutes les exigences. Mise à jour: Pour les commentaires, Java a également construit dans l'outil pour gérer les contrats de code: http://en.wikipedia.org/wiki/Java_Modeling_Language

Il est toujours bon de vérifier vos paramètres afin de s'assurer qu'ils sont bien définis -- pourquoi n'avez-vous pas envie de le faire avec un constructeur de trop?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X