Quand utiliser une assertion et quand utiliser une exception

la Plupart du temps, je vais utiliser une exception pour vérifier une condition dans mon code, je me demande quand c'est un moment approprié pour utiliser une affirmation?

par exemple,

Group group=null;
try{
    group = service().getGroup("abc");
}catch(Exception e){
    //I dont log error because I know whenever error occur mean group not found
}

if(group !=null)
{
    //do something
}

Pourriez-vous indiquer comment une affirmation s'inscrit dans ici? Devrais-je utiliser une affirmation?

il semble que je n'utilise jamais d'assertions dans le code de production et que je ne vois que des assertions dans les tests unitaires. Je sais que dans la plupart des cas, je peux juste utiliser l'exception pour faire la vérification comme ci-dessus, mais je veux savoir comment le faire "professionnellement".

102
demandé sur Machavity 2009-12-24 13:00:44

11 réponses

Affirmations devraient être utilisés pour vérifier quelque chose qui ne devrait jamais se produire, tandis qu'une exception doit être utilisé pour vérifier quelque chose qui pourrait se produire.

par exemple, une fonction peut se diviser par 0, donc une exception devrait être utilisée, mais une assertion pourrait être utilisée pour vérifier que le disque dur disparaît soudainement.

une assertion empêcherait le programme de fonctionner, mais une exception permettrait au programme de continuer à fonctionner.

Note que if(group != null) n'est pas une affirmation, c'est juste un conditionnel.

74
répondu Marius 2017-01-24 13:14:52

Hors de mon esprit (la liste peut être incomplète, et il est trop long pour tenir dans un commentaire), je dirais:

  • utiliser des exceptions pour vérifier les paramètres transmis au public ou aux méthodes et aux constructeurs protégés
  • utiliser des exceptions lorsque vous interagissez avec l'utilisateur ou lorsque vous vous attendez à ce que le code client se rétablisse d'une situation exceptionnelle
  • utiliser les exceptions pour résoudre les problèmes qui pourraient se produire
  • utilisation assertions lors de la vérification des pré-conditions, des post-conditions et des invariants de code privé / interne
  • utilisez des assertions pour fournir une rétroaction à vous-même ou à votre équipe de développeurs
  • utilisez des assertions pour vérifier des choses qui sont très peu susceptibles de se produire autrement, cela signifie qu'il ya une grave faille dans votre application
  • utilisez des affirmations pour énoncer des choses que vous (prétendument) savez être vraies

In autrement dit, les exceptions traitent de la robustesse de votre application tandis que les assertions traitent de son exactitude.

Affirmations sont conçus pour être facile à écrire, vous pouvez utiliser presque partout et je suis en utilisant cette règle de base: plus une assertion semble stupide, d'autant plus précieux qu'il est et le plus d'informations qu'elle incorpore. Lors du débogage d'un programme qui ne se comporte pas de la bonne manière, vous allez sûrement vérifier les possibilités de défaillance les plus évidentes sur la base de votre expérience. Ensuite, vous allez vérifier pour les problèmes qui ne peuvent tout simplement pas se produire: c'est exactement quand assertions aider beaucoup et gagner du temps.

155
répondu Gregory Pakosz 2009-12-24 10:03:20

souvenez-vous que les assertions peuvent être désactivées à l'exécution en utilisant des paramètres, et sont désactivées par défaut , donc ne comptez pas dessus sauf pour des fins de débogage.

aussi, vous devriez lire l'article Oracle à propos d'assert pour voir plus de cas où utiliser - ou ne pas utiliser - assert.

24
répondu chburd 2014-11-03 02:13:31

en règle générale:

  • utiliser des assertions pour les contrôles internes de cohérence où il n'est pas important du tout si quelqu'un les éteint. (Notez que la commande java éteint toutes les assertions par défaut.)
  • utilisez des tests réguliers pour tout type de contrôles Ce qui ne devrait pas être éteint. Ce inclut les contrôles défensifs qui protègent contre les dommages potentiels causés par les bogues, et toutes les données / requêtes de validation / tout ce qui est fourni par les utilisateurs ou les services externes.

le code suivant de votre question est mauvais style et potentiellement bogué

try {
    group = service().getGroup("abc");
} catch (Exception e) {
    //i dont log error because i know whenever error occur mean group not found
}

le problème est que vous ne savez pas qu'une exception signifie que le groupe n'a pas été trouvé. Il est également possible que l'appel service() ait fait une exception, ou qu'il ait retourné null qui a alors causé un NullPointerException .

quand vous attrapez une exception "attendue", vous devez attraper seulement l'exception que vous attendez. En capturant java.lang.Exception (et surtout en ne l'enregistrant pas), vous le rendez plus difficile à diagnostiquer / déboguer le problème, et potentiellement permettre à l'application de faire plus de dommages.

14
répondu Stephen C 2017-06-15 10:35:39

Selon cette doc http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general , "L'instruction assert est approprié pour vos préalable, postcondition et de la classe de contrôle d'invariant. Le contrôle préalable Public devrait toujours être effectué par des contrôles internes qui débouchent en particulier sur des exceptions documentées, telles que L'interception illégale de marchandises et L'interception illégale D'États."

Si vous voulez en savoir plus sur la condition préalable, la postcondition et l'invariant de classe, consultez ce doc: http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#usage-conditions . Il contient également avec des exemples d'allégations d'utilisation.

3
répondu cesarsalgado 2014-11-03 02:11:42

Eh bien, de retour chez Microsoft, la recommandation était de jeter des Exceptions dans tous les API que vous mettez à la disposition du public et L'utilisation affirme dans toutes sortes d'hypothèses que vous faites sur le code qui est interne. C'est un peu une définition générale, mais je suppose que c'est à chaque développeur de tracer la ligne.

en ce qui concerne L'utilisation des Exceptions, comme leur nom l'indique, leur utilisation devrait être exceptionnelle donc pour le code que vous présentez ci-dessus, l'appel getGroup devrait retourner null si non le service existe. Une Exception ne devrait se produire que si une liaison réseau tombe en panne ou quelque chose comme ça.

je suppose que la conclusion est qu'il est un peu laissé à l'équipe de développement pour chaque application de définir les limites d'assert vs exceptions.

3
répondu rui 2017-03-10 10:38:07

tester pour null ne capturera nulls causant des problèmes, alors qu'un essai/capture comme vous l'avez, il attrapera toute "erreur 151920920".

en gros, try / catch est plus sûr, mais légèrement plus lent, et vous devez faire attention que vous attrapez toutes les sortes d'erreurs qui peuvent se produire. Donc, je dirais d'utiliser essayer / attraper - un jour le code getGroup peut changer, et vous pourriez juste avoir besoin de ce plus grand filet.

1
répondu Phil H 2009-12-24 10:04:13

vous pouvez utiliser cette différence simple dans l'esprit pendant leur utilisation. Des Exceptions seront utilisées pour vérifier les erreurs attendues et inattendues appelées erreurs vérifiées et non vérifiées tandis que l'assertion est utilisée principalement à des fins de débogage au moment de l'exécution pour voir si les hypothèses sont validées ou non.

1
répondu SBTec 2012-06-11 09:37:26

j'avoue que je suis un peu confus par votre question. Lorsqu'une condition d'assertion n'est pas remplie, une exception est lancée. De prêter à confusion, ce qui est appelé AssertionError . Notez qu'il est non vérifié, comme (par exemple) IllegalArgumentException qui est jeté dans des circonstances très similaires.

donc en utilisant des assertions en Java

  1. est plus concis moyen de la rédaction d'un état/jeter bloc
  2. vous permet d'activer/désactiver ces contrôles via les paramètres JVM. Normalement, je laisserais ces vérifications en tout temps, à moins qu'elles n'aient un impact sur les performances d'exécution ou une pénalité similaire.
1
répondu Brian Agnew 2014-11-03 02:03:01

voir la section 6.1.2 (Assertions vs. other error code) de la documentation de Sun au lien suivant.

http://www.oracle.com/technetwork/articles/javase/javapch06.pdf

ce document donne les meilleurs conseils que j'ai vus sur le moment d'utiliser les assertions. Extrait du document:

"Une bonne règle de base est que vous devez utiliser une assertion pour des cas exceptionnels, que vous aimeriez oublier sur. Une affirmation est la façon la plus rapide de traiter, et d'oublier, une condition ou un État que vous ne vous attendez pas à avoir à traiter."

1
répondu Phil 2014-11-03 02:03:12

Malheureusement, affirme peut être désactivé. Quand dans la production vous avez besoin de toute l'aide que vous pouvez obtenir en traquant quelque chose d'imprévu, donc affirme disqualifier eux-mêmes.

0
répondu Thorbjørn Ravn Andersen 2012-06-18 08:57:23