105 votes

La différence entre try/catch/lancer et try/catch (e) / jeter e

Quelle est la différence entre

et

?

Et quand dois-je utiliser l’un ou l’autre ?

153voto

Bruno Reis Points 16132

Les constructions

try { ... }
catch () { ... } /* You can even omit the () here */

try { ... }
catch (Exception e) { ... }

sont semblables en ce que les deux va attraper toutes les exceptions lancées à l'intérieur de l' try bloc (et, sauf si vous êtes tout simplement à l'aide de ce journal les exceptions, doit être évité). Maintenant, regardez:

try { ... }
catch ()
{
    /* ... */
    throw;
}

try { ... }
catch (Exception e)
{
    /* ... */
    throw;
}

try { ... }
catch (Exception e)
{
    /* ... */
    throw e;
}

Les premier et deuxième blocs try-catch sont EXACTEMENT la même chose, ils se contentent de renvoyer à l'exception en cours, et que l'exception de garder sa "source" et la trace de la pile.

Le troisième bloc try-catch est différent. Quand il lève l'exception, il va changer la source et la trace de la pile, de sorte qu'il apparaît que l'exception a été levée à partir de cette méthode, à partir de ce ligne, throw e sur la méthode contenant le bloc try-catch.

On devrait vous utiliser? Cela dépend vraiment de chaque cas.

Disons que vous avez un Person classe avec un .Save() méthode qui va persister dans une base de données. Disons que votre application s'exécute l' Person.Save() méthode quelque part. Si votre DB refuse de sauver la Personne, alors .Save() lèvera une exception. Devriez-vous utiliser throw ou throw e dans ce cas? Eh bien, ça dépend.

Ce que je préfère, c'est de faire:

try {
    /* ... */
    person.Save();
}
catch(DBException e) {
    throw new InvalidPersonException(
       "The person has an invalid state and could not be saved!",
       e);
}

Cela devrait mettre la DBException comme le "Exception Interne" de la nouvelle exception jeter. Donc, lorsque vous examinez ce InvalidPersonException, la trace de la pile contiendra info retour à la méthode Save (qui pourrait être suffisant pour vous de résoudre le problème), mais vous avez toujours accès à l'exception d'origine devrait vous besoin.

Comme dernière remarque, quand vous attendent à une exception, vous devriez vraiment attraper une exception spécifique, et non générale Exception, c'est à dire, si vous vous attendez à un InvalidPersonException vous préférez:

try { ... }
catch (InvalidPersonException e) { ... }

pour

try { ... }
catch (Exception e) { ... }

Bonne chance!

35voto

Darin Dimitrov Points 528142

Le premier conserve la trace de la pile, tandis que la seconde se réinitialise. Cela signifie que si vous utilisez la deuxième approche de la trace de la pile de l'exception démarrera toujours à partir de cette méthode et vous perdrez l'exception d'origine trace qui pourraient être désastreuses pour quelqu'un de lire exception des journaux comme il ne saura jamais la cause d'origine de l'exception.

La deuxième approche peut être utile lorsque vous souhaitez ajouter des informations supplémentaires à la trace de la pile, mais il est utilisé comme ceci:

try
{
    // do something
}
catch (Exception ex)
{
    throw new Exception("Additional information...", ex);
}

Il y a un blog post discuter les différences.

6voto

Otávio Décio Points 44200

Vous devez utiliser

Si vous voulez faire quelque chose avec l’exception avant de re-jeter (exploitation forestière par exemple). Le lancer solitaire conserve la trace de la pile.

5voto

Guffa Points 308133

La différence entre un sans paramètre de capture et un catch(Exception e) , vous obtenez une référence à l'exception. À partir de framework version 2 exceptions non gérées sont enveloppés dans une exception, de sorte que le sans paramètre exception n'est plus utile pour quoi que ce soit.

La différence entre throw; et throw e; c'est que le premier est utilisé pour renvoyer les exceptions et la seconde est utilisée pour lancer une nouvelle exception à la règle. Si vous utilisez le second à renvoyer une exception, il va la considérer comme une nouvelle exception et remplacent toutes les informations de la pile à partir d'où il a été jeté.

Donc, vous shold pas utiliser de solutions de rechange à la question. Vous ne devez pas utiliser le sans paramètre de capture, et vous devez utiliser throw; de renvoyer une exception.

Aussi, dans la plupart des cas, vous devez utiliser une approche plus spécifique de la classe exception de la classe de base pour toutes les exceptions. Vous ne devez attraper les exceptions que vous prévoyez.

try {
   ...
} catch (IOException e) {
   ...
   throw;
}

Si vous souhaitez ajouter des informations lors de renvoi de l'exception, de vous créer une nouvelle exception à l'exception d'origine interne exception à preservere toutes les informations:

try {
   ...
} catch (IOException e) {
   ...
   throw new ApplicationException("Some informative error message", e);
}

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