web-dev-qa-db-fra.com

Exception par rapport à l'assertion

Quelle est la différence entre la gestion des exceptions Java et l'utilisation des conditions assert?

Il est connu qu'Assert est de deux types. Mais quand utiliser le mot-clé assert?

54
JavaResp

Utilisez des assertions pour les vérifications logiques internes dans votre code et des exceptions normales pour les conditions d'erreur hors du contrôle de votre code immédiat.

N'oubliez pas que les assertions peuvent être activées et désactivées - si vous vous souciez de choses comme la validation des arguments, cela devrait être explicite en utilisant des exceptions. (Vous pouvez cependant choisir d'effectuer la validation des arguments sur les méthodes private à l'aide d'assertions, au motif qu'une violation à ce stade est due à un bogue interne plutôt qu'à une erreur externe.)

Alternativement, il est tout à fait raisonnable (OMI) d'utiliser des exceptions pour tout. Personnellement, je n'utilise pas beaucoup d'assertions, mais c'est une question de préférence personnelle dans une certaine mesure. (Il peut certainement y avoir des arguments objectifs pour et contre des affirmations, mais ce n'est pas suffisamment clair pour supprimer complètement la préférence.)

83
Jon Skeet

Les assertions Java sont construites au-dessus des Java exceptions et gestion des exceptions. En effet, lorsqu'une assertion Java échoue, le résultat est une exception AssertionError qui peut être interceptée comme toute autre Java exception. Les principales différences entre les exceptions et les assertions sont les suivantes:

  • Les assertions sont destinées à être utilisées uniquement comme moyen de détecter les erreurs de programmation, alias les bogues. En revanche, une exception peut indiquer d'autres types d'erreur ou condition "exceptionnelle"; par exemple. entrée utilisateur non valide, fichiers manquants, tas plein, etc.
  • Le langage Java fournit un support syntaxique pour les assertions, sous la forme de l'instruction assert. Comparez les éléments suivants:

    if (x != y) {
         throw new SomeException("x != y");
    }
    
    assert x != y;
    
  • Plus important encore, Java vous permet d'activer ou de désactiver la vérification d'assertion globalement ou sur des classes individuelles lorsque vous démarrez la JVM.

Remarque: certaines personnes disent que vous devez toujours exécuter le code de production avec la vérification des assertions désactivée. J'ai tendance à être en désaccord avec cela comme une déclaration générale. Si votre code de production est connu pour être stable ET que vous devez en extraire le dernier bit de performances, désactiver les assertions est une bonne chose. Mais, si un (disons) 10% de performances n'est pas un problème réel, je préférerais qu'une application meure avec une erreur d'assertion si l'alternative est continue et corrompre ma base de données.

@Mario Ortegón a commenté ainsi:

La "désactivation" est due au fait que les assertions peuvent être utilisées pour vérifier le résultat d'un algorithme optimisé en comparant sa mise en œuvre à un algorithme bien connu, mais lent. Ainsi, en développement, il est OK d'invoquer cette méthode O(N^3) pour affirmer que l'algorithme O(log N) fonctionne comme prévu. Mais c'est quelque chose que vous ne voulez pas en production.

Que vous pensiez ou non bonne pratique pour désactiver les assertions en production, c'est certainement mauvaise pratique pour écrire des assertions qui ont un impact significatif sur les performances une fois activées. Pourquoi? Parce que cela signifie que vous n'avez plus la possibilité d'activer des assertions en production (pour tracer un problème) ou dans vos tests de stress/capacité. À mon avis, si vous devez faire O(N^3) des tests pré/post-condition, vous devriez le faire dans vos tests unitaires.

25
Stephen C

L'exception est un mécanisme permettant de vérifier si l'implémentation s'exécute sans erreur attendue ou inattendue ou non. Ainsi, nous voyons que les exceptions sont fondamentalement utilisées pour gérer même les conditions imprévues lors de l'exécution d'une application d'une meilleure manière et, par conséquent, l'utilisation des exceptions se traduit efficacement par une application robuste.

Les assertions ne doivent jamais faire partie de l'implémentation de certaines fonctionnalités de l'application. Ils ne doivent être utilisés que pour vérifier les hypothèses - juste pour être sûr que tout ce que nous avons supposé en concevant la solution est également valable dans la pratique.

référence: http://geekexplains.blogspot.com/2008/06/asserions-in-Java-assertions-vs.html

6
firstthumb

Les assertions sont très similaires aux exceptions, en fait, tout comme les exceptions, elles signalent un problème, mais contrairement aux exceptions - elles ne suggèrent aucun autre chemin d'exécution, mais échouent tout simplement. Pourquoi utiliser des assertions, si vous pouvez faire la même chose, et plus avec des exceptions?

Utilisez-les lorsque les problèmes ne doivent pas être résolus et NE DEVRAIENT JAMAIS SE PRODUIRE EN PREMIER LIEU. Cela semble bizarre au début: ne voulons-nous pas protéger notre code de TOUS les problèmes potentiels? Généralement oui. Mais il y a un cas où nous ne le faisons pas. Ce cas est appelé: "Design by contract".

Disons que vous écrivez une demande de banque. En tant que développeur, vous ne pouvez pas supporter toutes les conditions financières possibles. Donc, avant de commencer à coder, vous obtenez une spécification de la banque qui vous donne les plages valides que cette application devrait prendre en charge. Votre application est donc conçue par un contrat (selon les spécifications de la banque). Ce contrat définira les principes fondamentaux qui doivent toujours être vrais pour que votre application fonctionne. Ces principes fondamentaux sont appelés "invariants" (car ils ne peuvent pas changer). La conception par contrat vous simplifie la vie en tant que développeur - vous êtes uniquement responsable de soutenir la portée des travaux définis dans le contrat.
Il est important de vérifier les valeurs de ces invariants dans votre code, mais vous ne devez pas les vérifier comme s'il s'agissait d'exceptions et essayer de les contourner. S'ils se trompent - vous devez échouer parce que les intrants n'ont pas rempli leurs obligations contractuelles.

La chose intéressante est: si vous ne mettez pas une assertion à l'endroit critique et que les invariants deviennent invalides - votre code échouera de toute façon. Vous ne saurez simplement pas pourquoi. Donc, pour résumer - les assertions sont utilisées pour vérifier les invariants. Ils vont de pair avec le principe "design by contract". Utilisez-les pour déboguer un problème, c'est pourquoi ils sont désactivés en production.

Autre cas d'utilisation: si vous comptez sur une bibliothèque externe à laquelle vous ne faites pas entièrement confiance - vous pouvez utiliser des instructions assert lors de son appel.

Certains utilisent également des assertions comme un substitut rapide et sale à une exception (car c'est si facile à faire), mais conceptuellement, ce n'est pas la bonne chose à faire.

5
user2773898

Exemple d'une bonne utilisation de Assert:

assert flibbles.count() < 1000000; // too many flibbles indicate something is awry
log.warning("flibble count reached " + flibbles.count()); // log in production as early warning

Personnellement, je pense que Assert ne devrait être utilisé que lorsque vous savez que quelque chose est en dehors des limites souhaitable, mais vous pouvez en être sûr il est raisonnablement sûr de continuer. Dans toutes les autres circonstances (n'hésitez pas à signaler des circonstances auxquelles je n'ai pas pensé), utilisez les exceptions pour échouer fort et rapidement.

Le compromis clé pour moi est de savoir si vous voulez faire tomber un système en direct/de production avec une exception pour éviter la corruption et faciliter le dépannage, ou si vous avez rencontré une situation qui ne devrait jamais être autorisée à continuer inaperçue dans les versions de test/débogage mais pourrait être autorisé à continuer en production (enregistrement d'un avertissement bien sûr).

cf. http://c2.com/cgi/wiki?FailFast voir également ma copie c # de cette réponse: Debug.Assert vs Specific Thrown Exceptions

4
Tim Abell

L'assertion et la gestion des exceptions peuvent garantir l'exactitude du programme et éviter les erreurs logiques,

mais l'assertion peut activer et désactiver comme le souhaite le programmeur,

dans le compilateur si vous utilisez "Java -ea JavaFileName" ou "Java -enableasserations JavaFileName", vous pouvez compiler avec assertion

si les programmeurs n'en ont pas besoin, "Java -da JavaFileName" ou "Java -disableasserations JavaFileName", ils peuvent désactiver l'assertion.

cette installation n'est pas en traitement d'exception

1
Manjitha teshara

Assert est uniquement à des fins de débogage et sa condition de déclenchement ne doit pas se produire (pointeur nul quand il ne devrait pas y en avoir, etc.)

L'exception concerne les événements système spéciaux qui peuvent toujours se produire: FileNotFound, ConnectionToServerLost, etc.

1
Lliane

L'assertion est utilisée pour le débogage des hypothèses requises à vérifier au moment de l'exécution uniquement en activant la fonction d'assertion tandis que l'exception consiste à vérifier les conditions spécifiques à vérifier pendant l'exécution du programme pour empêcher le programme de se terminer.

0
SBTec