40 votes

Les blocs d'essai de Java doivent-ils être étendus aussi étroitement que possible?

J'ai dit qu'il y a une surcharge en utilisant le Java try-catch mécanisme. Ainsi, s'il est nécessaire de placer des méthodes qui jettent vérifié exception à l'intérieur d'un bloc try pour gérer l'exception possible, il est de bonne pratique au niveau des performances de limiter la taille du bloc try ne contiennent que celles de ces opérations qui pourraient lancer des exceptions.

Je ne suis pas si sûr que ce est une conclusion logique.

Considérons les deux implémentations ci-dessous d'une fonction qui traite un fichier texte spécifié.

Même si il est vrai que la première entraîne certains surcharge inutile, je trouve ça beaucoup plus facile à suivre. Il est difficile de savoir exactement où les exceptions viennent seulement de regarder des états, mais les observations montrent clairement quels états sont responsables.

Le second est beaucoup plus long et compliqué que le premier. En particulier, la belle ligne de lecture de l'idiome de la première a être déformés pour s'adapter à l' readLine appel dans un bloc try.

Quelle est la meilleure pratique pour la gestion des exceptions dans une fonction où de multiples exceptions pourraient être jeté dans sa définition?

Celui-ci contient tout le code de traitement dans le bloc try:

void processFile(File f)
{
  try
  {
    // construction of FileReader can throw FileNotFoundException
    BufferedReader in = new BufferedReader(new FileReader(f));

    // call of readLine can throw IOException
    String line;
    while ((line = in.readLine()) != null)
    {
      process(line);
    }
  }
  catch (FileNotFoundException ex)
  {
    handle(ex);
  }
  catch (IOException ex)
  {
    handle(ex);
  }
}

Celui-ci contient uniquement les méthodes qui renvoient des exceptions dans les blocs try:

void processFile(File f)
{
  FileReader reader;
  try
  {
    reader = new FileReader(f);
  }
  catch (FileNotFoundException ex)
  {
    handle(ex);
    return;
  }

  BufferedReader in = new BufferedReader(reader);

  String line;
  while (true)
  {
    try
    {
      line = in.readLine();
    }
    catch (IOException ex)
    {
      handle(ex);
      break;
    }

    if (line == null)
    {
      break;
    }

    process(line);
  }
}

45voto

erickson Points 127945

Le principe de base ici est faux: la taille d'un try bloc ne fait aucune différence dans la performance. La Performance est affectée par le fait d'élever des exceptions à l'exécution, et c'est indépendant de la taille de l' try bloc.

Toutefois, en gardant les blocs try petit peut conduire à de meilleurs programmes.

Vous pourriez attraper les exceptions à récupérer et à procéder, ou vous pourriez attraper, tout simplement, de les signaler à l'appelant (ou à l'homme, par l'intermédiaire de l'INTERFACE utilisateur).

Dans le premier cas, les échecs de à partir de laquelle vous pouvez récupérer sont souvent très spécifiques, ce qui conduit à de plus petits try blocs.

Dans le second cas, où une exception est attrapée, de sorte qu'il peut être enveloppé par une autre exception et re-jeté, ou de l'afficher à l'utilisateur, petit try blocs de dire que vous en savez plus précisément l'opération qui a échoué, et le contexte plus général dans lequel cet appel a été fait. Cela vous permet de créer plus spécifique des rapports d'erreur.

Bien sûr, il y a des exceptions... (désolé!) à ces lignes directrices. Par exemple, dans certains cas très spécifiques, les rapports d'erreur pourrait être un problème de sécurité.


Il pourrait être utile de savoir quel est l'effet d'un try bloc a sur le code compilé. Il ne change pas la compilation des instructions à tous! (Bien sûr, la correspondante catch bloc fait, puisque c'est comme n'importe quel autre code).

Un try bloc crée une entrée dans la table d'exception associée à la méthode. Cette table dispose d'un éventail de sources instructions compteurs, un type d'exception, et une destination d'instruction. Lorsqu'une exception est levée, ce tableau est examiné pour voir s'il existe une entrée avec un type, et une gamme qui comprend l'instruction qui a levé l'exception. Si elle le fait, branches d'exécution correspondant numéro de destination.

La chose importante à réaliser est que ce tableau n'est pas consulté (et n'a aucun effet sur les performances en cours d'exécution), sauf si cela est nécessaire. (Si l'on néglige un peu de surcharge dans le chargement de la classe.)

11voto

Jonathon Faust Points 7543

On m'a dit que l'utilisation du mécanisme Java try-catch entraînait une surcharge.

Absolument. Et il y a aussi des frais généraux pour les appels de méthode. Mais vous ne devriez pas mettre tout votre code dans une seule méthode.

Il ne faut pas oublier l'optimisation prématurée, mais l'accent doit être mis sur la facilité de lecture, l'organisation, etc. Les constructions de langage ont rarement une incidence sur les performances autant que sur l'organisation du système et le choix des algorithmes.

Pour moi, le premier est le plus facile à lire.

3voto

CurtainDog Points 2586

Non. La seule chose que vous devriez envisager est de savoir où vous pouvez raisonnablement gérer l'exception et quelles ressources vous devez récupérer (avec finalement).

2voto

luis.espinal Points 4145

C'est l'optimisation prématurée au pire. Ne le fais pas.

"Nous devrions oublier les petites efficacités, disons environ 97% du temps: l'optimisation prématurée est la racine de tout mal" - Knuth.

1voto

oedo Points 5438

il y a très très peu d'intérêt pour la 2ème méthode. après tout, si vous pouvez réussir à ouvrir un fichier, mais impossible de lire à partir, puis il ya quelque chose de mal avec votre ordinateur. ainsi, sachant que le io exception est venu de la readLine() la méthode est très rarement utile. aussi, comme vous le savez, les différentes exceptions sont levées pour des problèmes différents de toute façon (FileNotFoundException, etc)

aussi longtemps que vous avez portée avec une "logique" bloc, c'est à dire l'ouverture, la lecture et la fermeture d'un fichier de 1 go, je voudrais aller avec la première méthode. c'est beaucoup plus simple à lire et, surtout lorsqu'il s'agit d'IO, les cycles de processeur utilisé par le try-catch généraux serait minime, le cas échéant.

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