J'ai écrit une fonction qui demande à un utilisateur de saisir jusqu'à ce que l'utilisateur entre un entier positif (un nombre naturel). Quelqu'un a dit que je ne devrais pas lancer et intercepter des exceptions dans ma fonction et laisser l'appelant de ma fonction les gérer.
Je me demande ce que les autres développeurs en pensent. J'utilise également probablement des exceptions dans la fonction. Voici le code en Java:
private static int sideInput()
{
int side = 0;
String input;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("Side length: ");
input = scanner.nextLine();
try {
side = Integer.parseInt(input);
if (side <= 0) {
// probably a misuse of exceptions
throw new NumberFormatException();
}
}
catch (NumberFormatException numFormExc) {
System.out.println("Invalid input. Enter a natural number.");
}
} while (side <= 0);
return side;
}
Je m'intéresse à deux choses:
- Dois-je laisser l'appelant s'inquiéter des exceptions? Le point de la fonction est qu'elle harcèle l'utilisateur jusqu'à ce que l'utilisateur entre un nombre naturel. Le point de la fonction est-il mauvais? Je ne parle pas de l'interface utilisateur (l'utilisateur ne pouvant pas sortir de la boucle sans entrée appropriée), mais de l'entrée en boucle avec des exceptions gérées.
- Diriez-vous que l'instruction throw (dans ce cas) est une mauvaise utilisation des exceptions? Je pourrais facilement créer un indicateur pour vérifier la validité du numéro et afficher le message d'avertissement basé sur cet indicateur. Mais cela ajouterait plus de lignes au code et je pense qu'il est parfaitement lisible tel quel.
Le fait est que j'écris souvent une fonction d'entrée séparée. Si l'utilisateur doit saisir un nombre plusieurs fois, je crée une fonction distincte pour l'entrée qui gère toutes les exceptions et limitations de mise en forme.
exceptions
usr
la source
la source
Réponses:
Le point d'une exception est qu'elle permet à une méthode de dire à l'appelant qui est entré dans un état où il ne pouvait pas continuer normalement, sans vous forcer à incorporer un code d'erreur dans la valeur de retour.
Dans votre cas, votre méthode sait exactement quoi faire lorsque l'entrée n'est pas supérieure à 0. La seule raison pour laquelle vous enregistrez des lignes ici est que vous lancez la même exception que vous obtiendriez si l'entrée n'était pas un nombre. Cependant, l'exception que vous lancez ne représente pas correctement pourquoi votre code n'aime pas l'entrée. Si quelqu'un d'autre venait et voyait ce code, il devrait passer plus de temps à essayer de voir exactement comment les choses fonctionnent.
la source
C'est une mauvaise utilisation des exceptions. Pour commencer, un nombre non positif n'est pas une exception de format.
Pourquoi utiliser des exceptions? Si vous savez quelle entrée n'est pas autorisée, ne sortez pas de la boucle avant d'avoir obtenu une entrée valide de l'utilisateur, quelque chose comme ceci:
la source
Integer.parseInt()
jette unNumberFormatException
s'il ne peut pas analyser l'argument de chaîne fourni. Vous n'avez pas besoin (et vous ne pourrez pas) de lever l'exception vous-même.Integer.parseInt()
méthode lèvera l'exception pour vous si elle se produit, vous ne pourrez pas la lancer vous-même ensuite car elle a déjà été lancée.Ne capturez les exceptions que si vous avez l'intention de faire quelque chose qui est pertinent pour l'appel de méthode en cours; c.-à-d. nettoyage, logique d'échec, etc. Dans ce cas, le catch envoie simplement un message à la console, il n'est pas pertinent pour la méthode sideInput, il peut donc être traité plus haut dans la chaîne / pile d'appels.
On peut se débarrasser du try / catch ici et simplement documenter l'appel de méthode:
Il faut encore gérer cette exception plus haut dans la chaîne / pile d'appels!
la source
Vous ne devriez pas à la fois lancer et intercepter la même exception dans une méthode, je pense même que le bloc catch interceptera la même exception que vous lancez, donc vous ne la lancez pas vraiment.
Si cela
parseInt
a réussi, ce n'est pas le casNumberFormatException
.si le côté est inférieur à zéro, vous devez lancer un
NegativeSideLengthException
;Créer une exception personnalisée / commerciale nommée
NegativeSideLengthException
sideInput
Lance ensuite NegativeSideLengthExceptionVous pouvez même (si vous le souhaitez) ajouter un autre bloc catch à catch
NegativeSideLengthException
et ne pas demander à la méthode de le lancer.Les indicateurs ne sont pas un bon moyen de gérer les exceptions.
la source
Les exceptions sont des choses assez cauchemardesques, elles apportent plus de complexité qu'elles n'en résolvent.
Premièrement, si vous n'attrapez pas vos exceptions, l'appelant ne peut que le faire
on error resume next
, c'est-à-dire qu'au bout d'une semaine, même vous ne saurez pas ce que votre fonction peut lancer, et quoi en faire:Fondamentalement, si vous les attrapez, vous devez avoir une très bonne compréhension des contrats et des garanties d'exception. Cela se produit rarement dans un monde réel. Et aussi votre code sera difficile à lire.
De plus, ce qui est drôle, c'est que si vous avez vraiment une chance de gérer les exceptions, vous avez besoin d'un vrai langage RAII, qui est en quelque sorte humoristique, car Java et .NET sont tout au sujet des exceptions ...
Répéter encore une fois, mais ...:
http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx
http://www.joelonsoftware.com/items/2003/10/13.html
la source
: throw(thisexception, thatexception)
sont carrément erronées et ne devraient jamais être utilisées, car sinon vous obtiendrez inattendu sauf.catch
. Bien qu'une valeur de retour ignorée ne soit pas consultable - elle n'est identifiable que via une révision de code ligne par ligne. Enfin et surtout, les constructeurs n'ont pas de valeur de retour, c'est la principale raison d'utiliser des exceptions.