Étant donné: Throwable
est la superclasse de Exception
.
Lorsque je lis des textes sur l'écriture de vos propres "exceptions", je vois des exemples d'utilisation de Throwable
dans le bloc catch
et d'autres textes montrent que new Exception()
est utilisé dans le catch
. Je n'ai pas encore vu d'explication sur le moment où chacun devrait l'utiliser.
Ma question est la suivante: quand utiliser Throwable
et quand utiliser new Exception()
?
À l'intérieur du bloc catch
ou else
en utilisant soit:
throw throwable;
ou
throw new Exception();
(extrait des commentaires) Le problème qui a soulevé cette question est que je dois passer une "exception" à un morceau de code qu'un collègue construit si une collection n'est pas créée.
Dans ce cas, vous souhaiterez peut-être lever une exception vérifiée . Vous pouvez lancer un Exception
, une sous-classe existante appropriée de celui-ci (sauf RuntimeException
et ses sous-classes qui sont non cochée ), ou une sous-classe personnalisée de Exception
(par exemple "CollectionBuildException
"). Consultez le Tutoriel Java sur les exceptions pour vous familiariser avec les exceptions Java.
Lancez toujours un Exception
(jamais un Throwable
). Vous n'attrapez généralement pas Throwable
non plus, mais vous le pouvez. Throwable est la superclasse de Exception
et Error
, donc vous attraperiez Throwable
si vous vouliez non seulement attraper Exception
s mais Error
s, c'est le but de l'avoir. Le fait est que Error
s sont généralement des choses qu'une application normale ne devrait pas et ne devrait pas intercepter, donc utilisez simplement Exception
sauf si vous avez une raison spécifique d'utiliser Throwable
.
Vous ne devriez pas vraiment attraper une exception et en lancer une nouvelle aussi générale que "nouvelle exception".
Au lieu de cela, si vous souhaitez faire exploser l'exception, procédez comme suit:
try {
// Do some stuff here
}
catch (DivideByZeroException e) {
System.out.println("Can't divide by Zero!");
}
catch (IndexOutOfRangeException e) {
// catch the exception
System.out.println("No matching element found.");
}
catch (Throwable e) {
throw e; // rethrow the exception/error that occurred
}
Je crois que ce n'est pas une bonne pratique d'attraper une exception et de lancer une nouvelle exception au lieu de celle qui a été déclenchée dans votre bloc de code, sauf si vous déclenchez une exception personnalisée utile qui fournit suffisamment de contexte pour éluder la cause de l'exception d'origine. .
Seulement deux endroits, vous devriez voir le mot Throwable
dans le code:
public static void main(String args[])
{
try
{
// Do some stuff
}
catch(Throwable t)
{
}
}
ET
public class SomeServlet extends HttpServlet
{
public void doPost(HttpRequest request, HttpResponse response)
{
try
{
// Do some stuff
}
catch (Throwable t)
{
// Log
}
}
}
Throwable est une interface, pas une classe. Deux classes étendent Throwable, Exception et Error.
La règle est la suivante: soyez aussi précis que possible lorsque vous interceptez des exceptions - cela signifie par exemple intercepter Exception au lieu de Throwable, et IOException au lieu d'Exception.
Ne pas attraper les erreurs - les erreurs sont des bogues. Corrigez le code à la place.
Si vous devez attraper absolument tout, utilisez "catch Throwable", mais c'est une mauvaise forme.
throw new Exception();
est quelque chose que vous devriez jamais faire dans un bloc catch, mais vous devrez ou voudrez lancer new SomeException(throwable);
(en préservant la trace complète de la pile) à la place de throw throwable;
afin de se conformer à l'API de votre méthode, par exemple quand il déclare lancer SomeException
mais que vous appelez du code qui pourrait lancer une IOException
que vous ne voulez pas ajouter à la clause throws
de votre méthode.
Le cas probablement le plus courant est new RuntimeException(throwable);
pour éviter d'avoir une clause throws
tout à fait. Beaucoup de gens vous diront que c'est un horrible abus car vous devriez utiliser des exceptions vérifiées. OMI, ils sont faux et les exceptions vérifiées sont une erreur dans la conception du langage Java qui se traduit simplement par un code laid et incontrôlable.
Comme je l'ai entendu quand Java est sorti pour la première fois, la théorie était que Throwable pourrait être utilisé pour le transfert de contrôle dans d'autres cas, à l'exception des exceptions. Je ne l'ai jamais vu utiliser de cette façon (et c'est probablement une très bonne chose).
Il suffit donc d'attraper une exception (ou mieux encore, une exception plus fine).
Throwable est censé être capturé uniquement par le conteneur ou la boucle principale de votre programme. La plupart du temps, attraper des choses ci-dessous Exception, par exemple Erreur n'ajoute pas beaucoup de capacités à un programme, après tout, que pouvez-vous faire si une autre erreur VirtualError est levée. Pas grand chose à part se connecter et continuer.
Toutes les exceptions sont un problème à la fin ... trop dire que les erreurs sont des bugs ne veut rien dire.
Les erreurs ne sont pas des bogues - ce sont des problèmes rencontrés par l'hôte VM, par exemple OutOfMemoryError. Les exceptions sont un moyen que l'opération en cours peut utiliser pour signaler son échec et peut-être fournir un diagnostic.
Généralement, vous ne lancez pas ou n'attrapez pas Throwable. En particulier, les erreurs JVM (qui étendent Error ()) ne sont pas destinées à être détectées par le code utilisateur, sauf si vous effectuez un travail étrange au niveau du système.
Traitez "Throwable" comme un artefact de langage. La classe "Exception" est nommée ainsi car c'est celle qui est destinée à être utilisée par les programmeurs lorsqu'ils souhaitent qu'un bloc de code se termine "exceptionnellement" - en ne se fermant pas normalement ou en ne retournant pas de valeur.
Cela inclut à la fois les situations d'erreur régulières (par "régulière", je veux dire par opposition aux erreurs JVM) et les endroits où vous utilisez des exceptions comme mécanisme de contrôle.
Vous ne devez pas non plus utiliser les exceptions comme "type de retour" ...
Si la condition pour laquelle vous lancez est courante, vous dépensez une énorme quantité de ressources pour retourner cette condition à la routine d'appel. Les exceptions sont coûteuses à construire.
J'ai vu des cas où des boucles serrées qui lançaient des exceptions comme "négatives", par exemple L'allocation d'ID, cette routine occupait environ 99% du temps CPU .. lorsqu'elle est remplacée par une constante de retour documentée, elle tombe à 25%.