J'ai vu cette question, mais j'ai quelques autres questions sur l'utilisation du assert
mot clé. Je discutais avec quelques autres codeurs de l'utilisation assert
. Pour ce cas d'utilisation, il y avait une méthode qui peut retourner null si certaines conditions préalables sont remplies. Le code que j'ai écrit appelle la méthode, puis affirme qu'elle ne retourne pas null et continue d'utiliser l'objet renvoyé.
Exemple:
class CustomObject {
private Object object;
@Nullable
public Object getObject() {
return (object == null) ? generateObject() : object;
}
}
Imaginez maintenant que je l'utilise comme ceci:
public void useObject(CustomObject customObject) {
object = customObject.getObject();
assert object != null;
// Do stuff using object, which would throw a NPE if object is null.
}
On m'a dit que je devrais supprimer le assert
, qu'ils ne devraient jamais être utilisés dans le code de production, seulement utilisés dans les tests. Est-ce vrai?
-ea
ou équivalent.Objects.requireNonNull
Java 8).Réponses:
Utilisez
Objects.requireNonNull(Object)
pour cela.Dans votre cas, ce serait:
Cette fonction est faite aux fins que vous avez mentionnées, c'est-à-dire marquer explicitement ce qui ne doit pas être nul; également en production. Le grand avantage est que vous vous assurez de trouver des valeurs nulles là où elles ne devraient pas se produire en premier lieu. Vous aurez moins de problèmes de débogage causés par des valeurs nulles qui ont été passées quelque part où elles ne devraient pas être.
Un autre avantage est la flexibilité supplémentaire concernant les contrôles nuls contrairement à
assert
. Whileassert
est un mot-clé pour vérifier une valeur booléenne,Objects.requireNonNull(Object)
est une fonction et peut donc être intégré dans du code beaucoup plus flexible et lisible. Par exemple:Gardez à l'esprit que
Objects.requireNonNull(Object)
c'est uniquement pour la vérification nulle oùassert
est généralisé.assert
a des objectifs légèrement différents à cet égard, à savoir principalement les tests. Il doit être activé, vous pouvez donc l'activer pour les tests et le désactiver pour la production. Quoi qu'il en soit, ne l'utilisez pas pour le code de production. Cela pourrait ralentir l'application avec des validations inutiles et compliquées destinées aux tests. Utilisez-le pour séparer les chèques de test uniquement des chèques destinés également à la production.Consultez la documentation officielle pour plus de détails
assert
.la source
La chose la plus importante à retenir à propos des assertions est qu'elles peuvent être désactivées, alors ne supposez jamais qu'elles seront exécutées.
Pour des raisons de compatibilité descendante, la JVM désactive la validation d'assertion par défaut. Ils doivent être explicitement activés à l'aide de l'argument de ligne de commande -enableassertions ou de son raccourci -ea:
Donc, ce n'est pas une bonne pratique de compter sur eux.
Comme les assertions ne sont pas activées par défaut, vous ne pouvez jamais supposer qu'elles seront exécutées lorsqu'elles seront utilisées dans le code. Vous devez donc toujours vérifier les valeurs nulles et les options vides, éviter d'utiliser des assertions pour vérifier les entrées dans une méthode publique et utiliser à la place une exception non vérifiée ... En général, faites toutes les vérifications comme si l'assertion n'était pas là.
la source
Ce qu'on vous dit, c'est sûrement un mensonge flagrant. Voici pourquoi.
Les assertions sont désactivées par défaut si vous exécutez simplement jvm autonome. Lorsqu'elles sont désactivées, elles n'ont aucune empreinte, elles n'affecteront donc pas votre application de production. Cependant, ils sont probablement vos meilleurs amis lors du développement et du test de votre code, et la plupart des exécuteurs de framework de test activent les assertions (JUnit le fait), donc votre code d'assertion est exécuté lorsque vous exécutez vos tests unitaires, vous aidant à détecter tout bogue potentiel plus tôt (par exemple vous pouvez ajouter des assertions pour certaines vérifications des limites de la logique métier, ce qui aidera à détecter du code qui utilise des valeurs inappropriées).
Cela dit, comme l'autre réponse le suggère, pour exactement cette raison (elles ne sont pas toujours activées), vous ne pouvez pas vous fier aux assertions pour effectuer des vérifications vitales ou (surtout!) Maintenir un état.
Pour un exemple intéressant de la façon dont vous pouvez utiliser les assertions, jetez un œil ici - à la fin du fichier, il y a une méthode
singleThreadedAccess()
qui est appelée à partir de l'instruction assert à la ligne 201 et qui est là pour détecter tout accès multithread potentiel dans les tests.la source
Les autres réponses couvrent déjà suffisamment bien cela, mais il existe d'autres options.
Par exemple, Spring a une méthode statique:
org.springframework.util.Assert.notNull(obj)
Il existe également d'autres bibliothèques avec leurs propres
Assert.something()
méthodes. Il est également assez simple d'écrire le vôtre.Cependant, gardez à l'esprit les exceptions que vous jetez s'il s'agit d'un service Web. La méthode précédente mentionnée, par exemple, renvoie un
IllegalArgumentException
qui par défaut dans Spring renvoie un 500.Dans le cas d'un service Web, ce n'est souvent pas une erreur de serveur interne et ne doit pas être un 500, mais plutôt un 400, ce qui est une mauvaise demande.
la source
assert
est d'obtenir un crash immédiat avec un fichier core produit afin que vous puissiez faire un post-mortem avec votre débogueur préféré juste à l'endroit où la condition a été violée.assert
lancer. Intéressant. La version C / C ++ ne fait pas une telle chose. Il déclenche immédiatement un signal indiquant que a) tue le processus et b) crée un vidage de mémoire. Il le fait pour une raison: il est très simple de déboguer un tel échec d'assertion car vous avez toujours toutes les informations sur la pile d'appels disponibles. La définitionassert
de lever une exception à la place, qui peut ensuite être interceptée (non) intentionnellement par programme, va à l'encontre du but, à mon humble avis.Throwable
. Ils peuvent toujours être capturés. Que ce soit une bonne chose ou non, je ne sais pas. Je suppose que cela dépend. De nombreux programmes Java sont des services Web, et il ne serait pas souhaitable qu'il se bloque pour presque n'importe quelle raison, donc à peu près tout est capturé et enregistré. L'une des grandes choses est la trace de la pile, et c'est généralement suffisant pour diagnostiquer la raison d'une exception ou d'une erreur par elle-même.Utilisez les assertions généreusement chaque fois que cela aide à détecter les erreurs de programmation, par exemple les bogues.
N'utilisez pas assert pour attraper quelque chose qui pourrait logiquement se produire, par exemple une entrée mal formatée. N'utilisez assert que lorsque l'erreur est irrécupérable.
Ne placez aucune logique de production dans le code qui s'exécute lorsque l'assertion est vérifiée. Si votre logiciel est bien écrit, cela est trivialement vrai, mais si ce n'est pas le cas, vous pourriez avoir des effets secondaires subtils et un comportement global différent avec les assertions activées et désactivées.
Si votre entreprise dispose de "code de test" et de "code de production" faisant la même chose mais en tant que bases de code différentes (ou différentes étapes d'édition), sortez de là et ne revenez jamais. Essayer de corriger ce niveau d'incompétence est probablement une perte de temps. Si votre entreprise ne place aucune déclaration d'assertion en dehors du code des tests, veuillez lui dire que les assertions sont désactivées dans la génération de production et que si ce n'est pas le cas, la correction de cette erreur est maintenant votre première priorité.
La valeur des assertions doit précisément être utilisée dans la logique métier et pas seulement dans la suite de tests. Cela facilite la production de nombreux tests de haut niveau qui n'ont pas à tester explicitement beaucoup de choses pour parcourir de gros morceaux de votre code et déclencher toutes ces assertions. Dans quelques-uns de mes projets, les tests typiques n'ont même pas vraiment affirmé quoi que ce soit, ils ont simplement ordonné qu'un calcul se produise sur la base d'entrées spécifiques, ce qui a provoqué la vérification de centaines d'assertions et la découverte de problèmes, même dans de minuscules éléments de logique au fond.
la source
Vous pouvez utiliser assert à tout moment. Le débat est de savoir quand utiliser. Par exemple dans le guide :
la source