Quelle est la différence entre
et
?
Et quand dois-je utiliser l’un ou l’autre ?
Quelle est la différence entre
et
?
Et quand dois-je utiliser l’un ou l’autre ?
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!
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.
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 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.