La plupart du temps, je vais utiliser une exception pour rechercher une condition dans mon code. Je me demande quand il est temps d'utiliser une assertion?
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
}
Pouvez-vous indiquer comment une assertion s'inscrit ici? Devrais-je utiliser une affirmation?
Il semble que je n’utilise jamais d’assertions dans le code de production et que je ne les vois que dans les tests unitaires. Je sais que dans la plupart des cas, je peux simplement utiliser exception pour effectuer la vérification comme ci-dessus, mais je veux savoir comment procéder de manière "professionnelle".
Les assertions devraient être utilisées pour vérifier quelque chose qui ne devrait jamais arriver, alors qu'une exception devrait être utilisée pour vérifier quelque chose qui pourrait arriver.
Par exemple, une fonction peut être divisée par 0; une exception doit donc être utilisée, mais une assertion peut être utilisée pour vérifier que le disque dur disparaît subitement.
Une assertion arrêterait l'exécution du programme, mais une exception lui permettrait de continuer à s'exécuter.
Notez que if(group != null)
n'est pas une assertion, c'est juste une condition.
Hors de propos (la liste est peut-être incomplète et trop longue pour tenir dans un commentaire), je dirais:
En d'autres termes, les exceptions traitent de la robustesse de votre application tandis que les assertions traitent de son exactitude.
Les assertions sont conçues pour être peu coûteuses à l’écriture, vous pouvez les utiliser presque partout et j’utilise cette règle: plus une assertion a l’air stupide, plus elle a de la valeur et plus elle contient d’informations. Lors du débogage d'un programme qui ne se comporte pas correctement, vous allez sûrement vérifier les possibilités d'échec les plus évidentes en fonction de votre expérience. Ensuite, vous vérifierez si des problèmes ne peuvent pas se produire: c'est à ce moment précis que les assertions aident beaucoup et permettent de gagner du temps.
Rappelez-vous que les assertions peuvent être désactivées au moment de l'exécution à l'aide de paramètres, et sont désactivées par défaut , aussi ne les comptez pas, sauf à des fins de débogage.
Aussi, vous devriez lire l’article Oracle sur assert pour voir plus de cas où utiliser - ou ne pas utiliser - assert.
En règle générale:
Java
désactive toutes les assertions par défaut.)Le code suivant de votre question est mauvais style et potentiellement buggy
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 généré une exception ou qu'il ait renvoyé null
, ce qui a ensuite provoqué une NullPointerException
.
Lorsque vous attrapez une exception "prévue", vous devez attraper uniquement l'exception que vous attendez. En attrapant Java.lang.Exception
(et en particulier en ne le connectant pas), vous compliquez le diagnostic/le débogage du problème et vous permettez éventuellement à l'application de causer plus de dégâts.
De retour chez Microsoft, la recommandation était de créer des exceptions dans toutes les API que vous rendez publiques et de vous servir des assertions dans toutes sortes d'hypothèses que vous formulez sur du code interne. C'est une définition un peu vague, 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 doit être exceptionnelle. Ainsi, pour le code que vous présentez ci-dessus, l'appel getGroup
doit renvoyer null
s'il n'existe aucun service. Une exception ne devrait se produire que si un lien réseau tombe en panne ou quelque chose comme ça.
J'imagine que la conclusion est que l'équipe de développement a un peu laissé chaque application définir les limites d'assertion par rapport aux exceptions.
Selon ce document http://docs.Oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general , "L’affirmation assert est appropriée pour les conditions préalables non publiques, Les vérifications de précondition publique doivent toujours être effectuées à l'aide de vérifications effectuées à l'intérieur de méthodes entraînant notamment des exceptions documentées, telles que IllegalArgumentException et IllegalStateException. "
Si vous voulez en savoir plus sur les conditions préalables, postconditionnelles et invariantes de classe, consultez cette documentation: http://docs.Oracle.com/javase/6/docs/technotes/guides/language/assert.html#usage-conditions . Il contient également des exemples d'utilisation des assertions.
Tester Null ne détectera que les NULL, ce qui posera problème, alors qu’un catch/catch tel que vous le rencontrerez interceptera any error.
Globalement, essayer/intercepter est plus sûr, mais un peu plus lent, et vous devez faire attention à ne pas intercepter toutes les erreurs pouvant survenir. Donc, je dirais que utilisez try/catch - un jour, le code de getGroup pourrait changer, et vous pourriez avoir besoin de ce plus gros réseau.
Vous pouvez utiliser cette simple différence d’esprit pendant leur utilisation. Les 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 principalement utilisée à des fins de débogage au moment de l'exécution pour voir si les hypothèses sont validées ou non.
Voir la section 6.1.2 (Assertions vs. autre code d'erreur) de la documentation de Sun au lien suivant.
http://www.Oracle.com/technetwork/articles/javase/javapch06.pdf
Ce document donne le meilleur conseil que j'ai vu sur le moment d'utiliser des assertions. Citant le document:
"En règle générale, vous devez utiliser une assertion pour les cas exceptionnels que vous voudriez oublier. Une assertion est le moyen le plus rapide de traiter, et d'oublier, une condition traiter avec."
J'avoue que votre question me laisse un peu perplexe. Lorsqu'une condition d'assertion n'est pas remplie, une exception est levée. Confusément, cela s'appelle AssertionError . Notez qu'il est décoché, comme (par exemple) IllegalArgumentException , qui est levé dans des circonstances très similaires.
Donc, en utilisant des assertions en Java
Malheureusement, les assertions peuvent être désactivées. Lorsque vous êtes en production, vous avez besoin de toute l'aide dont vous avez besoin pour dépister quelque chose d'imprévu, affirme-t-il, se disqualifie.