84 votes

True-way solution en Java : 2 nombres de 2 cordes et retourne alors leur somme

Tout à fait une question stupide. Étant donné le code:

public static int sum(String a, String b) /* throws? WHAT? */ {
  int x = Integer.parseInt(a); // throws NumberFormatException
  int y = Integer.parseInt(b); // throws NumberFormatException
  return x + y;
}

Pourriez-vous dire si c'est bon Java ou pas? Ce que je suis en train de parler, NumberFormatException est un décoché exception. Vous n'avez pas à spécifier en tant que partie de l' sum() signature. De plus, comme je le comprends, l'idée de décoché exceptions est juste pour signaler que la mise en œuvre du programme est incorrect, et même plus, la capture décoché des exceptions est une mauvaise idée, puisque c'est comme la fixation du mauvais programme au moment de l'exécution.

Quelqu'un voudrait-il préciser si:

  1. Je dois préciser NumberFormatException comme une partie de la signature de la méthode.
  2. Je dois définir mon propre vérifié exception (BadDataException), la poignée NumberFormatException à l'intérieur de la méthode et de re-jeter aussi BadDataException.
  3. Je dois définir mon propre vérifié exception (BadDataException), de valider les deux chaînes d'une certaine façon comme des expressions régulières et de jeter mon BadDataException si elle ne correspond pas.
  4. Votre idée?

Mise à jour:

Imaginez, ce n'est pas une structure open-source, que vous devez utiliser pour une raison quelconque. Vous regardez la signature de la méthode et de penser - "OK, il ne jette". Puis, un jour, vous avez eu une exception. Est-il normal?

Mise à jour 2:

Il y a quelques commentaires disant que mon sum(String, String) est une mauvaise conception. Je n'ai absolument d'accord, mais pour ceux qui croient que le problème serait tout simplement de ne jamais apparaître si nous avons eu un bon design, voici une question supplémentaire:

La définition du problème, qui est comme ceci: vous avez une source de données où les nombres sont stockés en tant que Strings. Cette source peut être un fichier XML, web page, la fenêtre du bureau avec 2 zones d'édition, que ce soit.

Votre objectif est de mettre en œuvre la logique qui prend ces 2 Strings, les convertit en ints et affiche la boîte de message disant "la somme est de xxx".

Peu importe ce que l'approche que vous utilisez pour concevoir et mettre en œuvre ce, vous serez d' avoir ces 2 points de l'intérieur de la fonctionnalité:

  1. Un endroit où vous convertir String de int
  2. Un endroit où vous ajoutez 2 ints

La question principale de mon post original est:

Integer.parseInt() s'attend à corriger une chaîne à transmettre. Chaque fois que vous passez une mauvaise chaîne, cela signifie que votre programme est incorrect (et non pas "votre utilisateur est un idiot"). Vous avez besoin de mettre en œuvre le morceau de code où d'une part Entier.parseInt() DOIT sémantique et d'autre part, vous devez être OK avec le cas lorsque l'entrée est incorrecte DOIT sémantique.

Donc, en bref: comment puis-je mettre en œuvre DOIT sémantique si je n'ai que DOIT bibliothèques.

49voto

Johan Sjöberg Points 20759

À mon avis, il serait préférable de gérer logique d'exception aussi loin que possible. Donc, je préfère la signature

 public static int sum(int a, int b);

Avec votre signature de la méthode, je voudrais pas changer quoi que ce soit. Soit vous êtes

  • Par programmation à l'aide des valeurs incorrectes, où vous plutôt de valider votre producteur algorithme
  • ou l'envoi de valeurs, par exemple, la saisie de l'utilisateur, auquel cas ce module doit effectuer la validation

Par conséquent, la gestion des exceptions dans ce cas devient une documentation en question.

35voto

Bohemian Points 134107

C'est une bonne question. Je souhaite que plus de gens pourraient penser de telles choses.

À mon humble avis, jetant décoché des exceptions est acceptable si vous avez passé des ordures paramètres.

En règle générale, vous ne devriez pas jeter BadDataException parce que vous ne devriez pas utiliser des Exceptions afin de contrôler le flux du programme. Les Exceptions sont pour l'exceptionnel. Les appelants à votre méthode peut le savoir avant de l'appellent-ils si leurs chaînes sont des nombres ou pas, donc en passant les ordures peuvent être évités, et peut donc être considéré comme une erreur de programmation, ce qui signifie qu'il est OK pour lancer décoché exceptions.

Concernant déclarant throws NumberFormatException - ce n'est pas très utile, parce que peu de préavis en raison de l'NumberFormatException être décochée. Cependant, les IDE peuvent l'utiliser et offre de conclure en try/catch correctement. Une bonne option est d'utiliser la javadoc ainsi, par exemple:

/**
 * Adds two string numbers
 * @param a
 * @param b
 * @return
 * @throws NumberFormatException if either of a or b is not an integer
 */
public static int sum(String a, String b) throws NumberFormatException {
    int x = Integer.parseInt(a); 
    int y = Integer.parseInt(b); 
    return x + y;
}

MODIFIÉ:
Les intervenants ont fait des points valides. Vous devez considérer comment il sera utilisé et la conception globale de votre application.

Si la méthode sera utilisée partout, et il est important que tous les appelants de résoudre les problèmes, la déclaration de la méthode que de lancer un checked exception (ce qui oblige les appelants à résoudre les problèmes), mais encombrer le code avec try/catch blocs.

En revanche, si nous sommes à l'aide de cette méthode avec des données nous faire confiance, de le déclarer comme ci-dessus, car il n'est pas prévu à jamais exploser et vous éviter l'encombrement de code de essentiellement inutiles try/catch blocs.

5voto

jmoreno Points 6995

Numéro 4. Comme donné, cette méthode ne devrait pas prendre de chaînes que les paramètres qu'il doit prendre des entiers. Auquel cas (depuis java wraps au lieu de déborder) il n'y a aucune possibilité d'une exception.

 x = sum(Integer.parseInt(a), Integer.parseInt(b))

est beaucoup plus claire que ce que l'on entend que x = sum(a, b)

Vous voulez l'exception pour arriver comme près de la source (input) que possible.

Comme pour les options 1 à 3, vous ne définissez pas une exception parce que vous attendez de vos appelants de supposer que sinon, votre code ne peut pas échouer, vous définissez une exception à définir ce qui se passe en vertu de l'échec connu des conditions QUI SONT UNIQUES À VOTRE MÉTHODE. I. e. si vous avez une méthode qui est un wrapper autour d'un autre objet, et elle lève une exception de le passer. Seulement si l'exception est unique à votre méthode à vous lever une exception personnalisée (frex, dans votre exemple, si la somme était censé que le retour à des résultats positifs, alors, le contrôle et lancer une exception serait le cas, si d'autre part java généré une exception de dépassement de la place de l'emballage, puis vous passerez le long de, définit pas dans votre signature, de le renommer ou de le manger).

Mise à jour en réponse à la mise à jour de la question:

Donc, en bref: comment puis-je mettre en oeuvre DEVRAIT sémantique si je n'ai que DOIT bibliothèques.

La solution à ce problème consiste à envelopper le must de la bibliothèque, et de retourner une valeur DOIT. Dans ce cas, une fonction qui renvoie un Entier. Écrire une fonction qui prend une chaîne de caractères et renvoie un objet Integer -- soit ça fonctionne, soit il renvoie la valeur null (comme la goyave de l'Ints.tryParse). Faites de votre validation séparé de votre fonctionnement, votre opération doit prendre ints. Si votre opération est appelée avec des valeurs par défaut lorsque vous avez entrée non valide, ou que vous fassiez autre chose, dépendra de vos spécifications techniques, pour la plupart, je peux dire à ce sujet, est qu'il est très peu probable que l'endroit pour faire de cette décision est dans la méthode de fonctionnement.

3voto

maaartinus Points 12510

1. Je dois préciser NumberFormatException comme une partie de la signature de la méthode.

Je pense que oui. C'est une belle documentation.

2. Je dois définir mon propre vérifié exception (BadDataException), la poignée NumberFormatException à l'intérieur de la méthode et de re-jeter aussi BadDataException.

Parfois, oui. L'objet d'exceptions sont à considérer pour être mieux dans certains cas, mais le fait de travailler avec eux, c'est tout à fait un pain PITA. C'est pourquoi de nombreux cadres (par exemple, la mise en veille) l'utilisation des exceptions d'exécution seulement.

3. Je dois définir mon propre vérifié exception (BadDataException), de valider les deux chaînes d'une certaine façon comme des expressions régulières et de jeter mon BadDataException si elle ne correspond pas.

Jamais. Plus de travail, moins de vitesse (sauf si vous vous attendez à jeter de l'exception à une règle), et aucun gain.

4. Votre idée?

Pas du tout.

2voto

Farmor Points 4928

Nr 4.

Je pense que je ne changerais pas du tout la méthode. Je mettrais un try catch autour de la méthode d’appel ou plus dans la trace de la pile où je suis dans un contexte où je peux récupérer gracieusement avec la logique métier de l’exception.

Je ne voudrais pas do #3 de la certitude que j’ai le jugent excessif.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X