Est-ce une bonne pratique connue d'utiliser un gros try-catch par méthode en java? [fermé]


J'ai été interviewé récemment et l'intervieweur voulait que je fasse un test technique pour voir mes connaissances. Après l'avoir terminé, il m'a donné des commentaires sur la façon dont je l'ai fait, ce à quoi je ne m'attendais pas et j'ai apprécié, car peu d'intervieweurs le font s'ils ne veulent pas vous embaucher.

L'une des choses qu'il m'a dit qu'il voyait mal mon code était que j'ai utilisé plus d'un bloc try-catch dans chaque méthode que j'ai écrite. Cela attire mon attention car je le vois intéressant.

Je crois à le moment où je devrais faire des blocs try-catch où il y a un bloc de code sémantiquement distinguable qui a une ou plusieurs méthodes qui peuvent lancer des exceptions devait être intercepté. La seule exception à cela que j'ai suivie était que si deux méthodes lancent le même type d'exception, je ferais mieux de les mettre dans différents blocs try-catch pour distinguer clairement lors du débogage où et pourquoi une exception a été levée.

Cela diffère fortement de ce que l'intervieweur voulait que je fasse. Ainsi est l'utilisation un seul bloc try-catch par méthode une bonne pratique connue? S'il s'agit d'une bonne pratique connue, quels sont les avantages de la faire?

EDIT: J'apprécie grandement vos réflexions à ce sujet, c'est très bon. Bien que prendre note que je demande si c'est une bonne pratique connue. C'est, si la plupart des programmeurs seraient d'accord sur ce point, et ou c'est écrit comme une bonne pratique dans certains livre

Author: Gianmarco, 2013-09-13

7 answers

Pour moi, deux blocs try-catch rendent la plupart des méthodes trop longues. Il obscurcit l'intention si la méthode fait beaucoup de choses.

Avec deux blocs try-catch, il fait au moins quatre choses, pour être précis

  • deux cas pour le flux principal (deux blocs d'essai)
  • deux cas pour la gestion des erreurs (catch)

Je préfère faire des méthodes courtes et claires à partir de chaque bloc try-catch - like

private getHostNameFromConfigFile(String configFile, String defaultHostName) {
    try {
        BufferedReader reader = new BufferedReader(new FileReader(configFile));
        return reader.readLine();
    } catch (IOException e) {
        return defaultHostName;
    }
}
public Collection<String> readServerHostnames(File mainServerConfigFile, File  backupServerConfigFile) {
    String mainServerHostname=getHostNameFromConfigFile(mainServerConfigFile,"default- server.example.org");
    String backupServerHostName=getHostNameFromConfigFile(backupServerConfigFile,"default- server.example.ru")
    return Arrays.asList(mainServerHostname,backupServerHostName );
}

Robert C. Martin dans' Clean Code ' le fait passer au niveau supérieur, suggérant:

Si le mot-clé 'try' existe dans une fonction, ce devrait être le tout premier mot de la fonction et qu'il ne devrait y avoir rien après le catch/finally blocks.

Je refactoriserais certainement la méthode avec deux blocs try/catch distincts en méthodes plus petites.

 33
Author: Bartosz Bilicki, 2016-05-18 04:42:46

Je dirais que si vous vous retrouvez à envelopper deux blocs de code distincts avec try/catch, vous devriez envisager de refactoriser ces blocs dans des méthodes distinctes. Si c'est un modèle que vous avez utilisé dans votre interview, vous avez peut-être mal compris votre intervieweur.

Il est parfaitement correct d'utiliser deux blocs try/catch si l'algorithme l'exige. J'ai souvent utilisé un nouveau try/catch dans un bloc de capture pour assurer un nettoyage sûr, de sorte qu'une déclaration générale n'est pas possible.

 28
Author: OldCurmudgeon, 2013-09-13 11:00:27

Pour répondre à votre question, lorsque nous parlons de JVM modernes qui appliquent en fait beaucoup d'optimisations dans le code, lorsque vous écrivez du code inefficace, la JVM introduira automatiquement des optimisations.

Veuillez vous référer à la réponse dans (Java: surcharge de saisie/utilisation de blocs "try-catch"?).

Donc, la bonne pratique n'a pas beaucoup d'importance.

Sur une note personnelle, je crois qu'il ne faut rien encapsuler dans un try-catch, static, synchronized etc bloque non nécessairement.

Rendons notre code plus lisible pour ceux qui y travailleront. Si une exception est attrapée, il est préférable de la rendre explicitement visible quel morceau de code la lance.

Pas de devinettes pour le lecteur, c'est pourquoi les JVM sont intelligentes, écrivent comme vous voulez , le rendent meilleur pour les humains et la JVM s'occupe de la partie optimisation.

EDIT: J'ai lu beaucoup de livres et je ne l'ai trouvé aucun endroit qui dit cette grosse prise d'essai est meilleure que plusieurs petites.

De plus, beaucoup dans la communauté des développeurs croient le contraire.

 13
Author: dharam, 2017-05-23 11:54:50

J'essaie d'éviter la duplication dans les blocs de capture. Si toutes les exceptions d'une méthode reçoivent le même traitement dans le bloc catch, alors allez-y et attrapez-les toutes ensemble. Si vous devez faire différentes choses avec eux, attrapez-les séparément.

Par exemple, ici, nous pouvons attraper toutes les exceptions ensemble, car tout type d'exception signifie que toute la méthode échoue:

public PasswordAuthentication readAuthenticationDetails(File authenticationFile) {
    try {
        BufferedReader reader = new BufferedReader(new FileReader(authenticationFile));
        String username = reader.readLine();
        String password = reader.readLine();
        return new PasswordAuthentication(username, password.toCharArray());
    } catch (IOException e) {
        return null;
    }
}

Alors qu'ici, nous avons un comportement de repli différent pour chaque groupe d'appels, nous attrapons donc séparément:

public Collection<String> readServerHostnames(File mainServerConfigFile, File backupServerConfigFile) {
    String mainServerHostname;
    try {
        BufferedReader reader = new BufferedReader(new FileReader(mainServerConfigFile));
        mainServerHostname = reader.readLine();
    } catch (IOException e) {
        mainServerHostname = "default-server.example.org";
    }

    String backupServerHostname;
    try {
        BufferedReader reader = new BufferedReader(new FileReader(backupServerConfigFile));
        backupServerHostname = reader.readLine();
    } catch (IOException e) {
        backupServerHostname = "default-server.example.ru";
    }

    return Arrays.asList(mainServerHostname, backupServerHostname);
}

(Ce code existe uniquement pour illustrer ce point sur la capture des exceptions; je vous prie de ne pas tenir compte du fait que c'est tout à fait horrible d'une autre manière)

 8
Author: Tom Anderson, 2013-09-13 17:19:22

Quant à moi, il est plus clair d'avoir un seul bloc try-catch enveloppant tout le code 'dangereux' dans une méthode. En ce qui concerne qui blâmer lorsque deux lignes lancent la même exception, vous aurez toujours la stacktrace.

En outre, avoir plus d'un try-catch dans une méthode signifie généralement avoir plus d'une return lignes (ce qui peut également rendre difficile de suivre l'exécution du code à vue), car il est probable que si quelque chose ne va pas dans le premier try-catch, cela n'aura pas de sens de continuer à exécuter le reste de la code.

Ici vous pouvez trouver quelques bonnes pratiques "standard", juste au cas où vous pourriez les trouver utiles.-

Http://howtodoinjava.com/2013/04/04/java-exception-handling-best-practices/

 6
Author: ssantos, 2013-09-13 11:19:25

C'est une autre chose qui démarre souvent Java-flamewar... ;-)

Fondamentalement, pour la performance ne compte que lancer des exceptions. Donc, l'utilisation de quelques blocs try-catch ne devrait pas affecter une performance du tout. Dans certains avis, écrire du code de cette façon obscurcit le code et ne rappelle même pas le "code propre", dans d'autres avis, il est préférable d'utiliser try uniquement pour les lignes qui peuvent réellement lever une exception.

C'est à vous de décider (ou à la convention d'équipe).

 5
Author: Eel Lee, 2013-09-13 10:58:03

, Il est également important de considérer le contexte du code. Si vous écrivez du code avec des E / S lourdes, vous devrez peut-être savoir quelles parties du code échouent. Je n'ai pas encore vu nulle part un point qui essaie...catch est destiné à vous donner une chance de récupérer d'un problème.

Donc, si vous obtenez une exception d'E / S en lecture à partir d'un fichier, vous pouvez réessayer la lecture. Même chose avec l'écriture. Mais si vous aviez un grand essai...attraper vous ne sauriez pas lequel réessayer.

 5
Author: Chris, 2013-09-13 16:01:01