Je crains qu'il ne s'agisse d'une exception d'exécution, donc elle devrait probablement être utilisée avec parcimonie.
Cas d'utilisation standard:
void setPercentage(int pct) {
if( pct < 0 || pct > 100) {
throw new IllegalArgumentException("bad percent");
}
}
Mais cela semble forcer la conception suivante:
public void computeScore() throws MyPackageException {
try {
setPercentage(userInputPercent);
}
catch(IllegalArgumentException exc){
throw new MyPackageException(exc);
}
}
Pour qu'il redevienne une exception vérifiée.
D'accord, mais allons-y avec ça. Si vous donnez une mauvaise entrée, vous obtenez une erreur d'exécution. Donc, tout d'abord, c'est en fait une politique assez difficile à mettre en œuvre uniformément, car vous pourriez avoir à faire la conversion tout à fait inverse:
public void scanEmail(String emailStr, InputStream mime) {
try {
EmailAddress parsedAddress = EmailUtil.parse(emailStr);
}
catch(ParseException exc){
throw new IllegalArgumentException("bad email", exc);
}
}
Et pire - alors que la vérification 0 <= pct && pct <= 100
du code client pourrait être censée faire de manière statique, ce n'est pas le cas pour des données plus avancées telles qu'une adresse e-mail, ou pire, quelque chose qui doit être vérifié par rapport à une base de données, donc en général, le code client ne peut pas pré- valider.
Donc, fondamentalement, ce que je dis, c'est que je ne vois pas de politique cohérente significative pour l'utilisation de IllegalArgumentException
. Il semble qu'il ne devrait pas être utilisé et que nous devrions nous en tenir à nos propres exceptions vérifiées. Quel est un bon cas d'utilisation pour lancer cela?
la source
Lorsque vous parlez de "mauvaise entrée", vous devez considérer d'où provient l'entrée.
Est-ce que l'entrée est entrée par un utilisateur ou un autre système externe que vous ne contrôlez pas, vous devez vous attendre à ce que l'entrée soit invalide et toujours la valider. Il est parfaitement normal de lancer une exception cochée dans ce cas. Votre application doit «récupérer» de cette exception en fournissant un message d'erreur à l'utilisateur.
Si l'entrée provient de votre propre système, par exemple votre base de données, ou d'autres parties de votre application, vous devriez pouvoir compter sur elle pour être valide (elle devrait avoir été validée avant d'y arriver). Dans ce cas, il est parfaitement possible de lancer une exception non vérifiée comme une IllegalArgumentException, qui ne devrait pas être interceptée (en général, vous ne devriez jamais intercepter les exceptions non vérifiées). C'est une erreur du programmeur que la valeur invalide y soit arrivée en premier lieu;) Vous devez la corriger.
la source
Because an unchecked exception is meant to be thrown as a result of a programming error
m'a aidé à nettoyer beaucoup de choses dans ma tête, merci :)Lancer des exceptions d'exécution "avec parcimonie" n'est pas vraiment une bonne politique - Effective Java recommande d'utiliser des exceptions vérifiées lorsque l'appelant peut raisonnablement être appelé à récupérer . (L'erreur de programmeur est un exemple spécifique: si un cas particulier indique une erreur de programmeur, vous devez alors lancer une exception non vérifiée; vous voulez que le programmeur ait une trace de pile de l'endroit où le problème de logique s'est produit, pas d'essayer de le gérer vous-même.)
S'il n'y a aucun espoir de récupération, n'hésitez pas à utiliser des exceptions non cochées; il ne sert à rien de les attraper, donc c'est parfaitement bien.
Cependant, il n'est pas clair à 100% dans votre exemple dans quel cas cet exemple est dans votre code.
la source
foo(data)
aurait pu se produire dans le cadre defor(Data data : list) foo(data);
laquelle l'appelant pourrait souhaiter que le plus grand nombre réussisse, même si certaines données sont mal formées. Inclut également les erreurs de programmation, si l'échec de mon application signifie qu'une transaction ne sera pas exécutée, c'est probablement mieux, si cela signifie que le refroidissement nucléaire est hors ligne, c'est mauvais.StackOverflowError
et tels sont des cas dont on ne peut raisonnablement s'attendre à ce que l'appelant récupère. Mais il semble que tout cas de niveau logique de données ou d'application devrait être vérifié. Cela signifie faire vos vérifications de pointeur nul!Comme spécifié dans le didacticiel officiel d'Oracle, il indique que:
Si j'ai une application interagissant avec la base de données à l'aide de
JDBC
, Et j'ai une méthode qui prend l'argument comme leint item
etdouble price
. L'price
élément correspondant pour est lu à partir de la table de base de données. Je multiplie simplement le nombre total d'item
achat par laprice
valeur et renvoie le résultat. Bien que je sois toujours sûr de mon côté (côté application) que la valeur du champ de prix dans le tableau ne peut jamais être négative. Mais que se passe-t-il si la valeur du prix est négative ? Cela montre qu'il y a un problème sérieux avec la base de données. Peut-être une mauvaise entrée de prix par l'opérateur. C'est le genre de problème que l'autre partie de l'application appelant cette méthode ne peut pas anticiper et ne peut pas y remédier. C'est unBUG
dans votre base de données. Alors, etIllegalArguementException()
devrait être jeté dans ce cas qui indiquerait quethe price can't be negative
.J'espère avoir exprimé clairement mon point de vue.
la source
Toute API doit vérifier la validité de chaque paramètre de toute méthode publique avant de l'exécuter:
Ils représentent 99,9% des fois des erreurs dans l'application car elle demande des opérations impossibles donc à la fin ce sont des bogues qui devraient planter l'application (c'est donc une erreur non récupérable).
Dans ce cas et en suivant l'approche de l'échec rapide, vous devez laisser l'application se terminer pour éviter de corrompre l'état de l'application.
la source
Traitez
IllegalArgumentException
comme une vérification des conditions préalables et considérez le principe de conception: une méthode publique devrait à la fois connaître et documenter publiquement ses propres conditions préalables.Je conviens que cet exemple est correct:
Si EmailUtil est opaque , ce qui signifie qu'il y a une raison pour laquelle les conditions préalables ne peuvent pas être décrites à l'utilisateur final, alors une exception vérifiée est correcte. La deuxième version, corrigée pour cette conception:
Si EmailUtil est transparent , par exemple c'est peut-être une méthode privée appartenant à la classe en question, elle
IllegalArgumentException
est correcte si et seulement si ses conditions préalables peuvent être décrites dans la documentation de la fonction. Ceci est également une version correcte:Cette conception pourrait aller dans les deux sens.
ParseException
. La méthode de niveau supérieur ici est nommée,scanEmail
ce qui indique que l'utilisateur final a l'intention d'envoyer des e-mails non étudiés, ce qui est probablement correct.IllegalArgumentException
. Bien que non "coché", le "chèque" se déplace vers le Javadoc documentant la fonction, à laquelle le client est censé adhérer.IllegalArgumentException
où le client ne peut pas dire à l'avance que son argument est illégal est faux.Une note sur IllegalStateException : Cela signifie que "l'état interne de cet objet (variables d'instance privée) n'est pas en mesure d'effectuer cette action." L'utilisateur final ne peut pas voir l'état privé si vaguement qu'il a la priorité sur
IllegalArgumentException
le cas où l'appel client n'a aucun moyen de savoir que l'état de l'objet est incohérent. Je n'ai pas une bonne explication quand elle est préférée aux exceptions vérifiées, bien que des choses comme l'initialisation deux fois ou la perte d'une connexion à une base de données non récupérée en soient des exemples.la source