web-dev-qa-db-fra.com

Quand Throwable devrait-il être utilisé au lieu d'une nouvelle exception?

É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();
40
WolfmanDragon

(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.

14
Zach Scrivena

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 Exceptions mais Errors, c'est le but de l'avoir. Le fait est que Errors 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.

37
Ray Hidayat

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. .

8
MichaelD

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
         }
      }
 }
5
uranazo

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.

1
Michiel de Mare

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.

1
Michael Borgwardt

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).

0
Bill K

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.

0
mP.

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.

0
mP.

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.

0
Paul Murray

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%.

0
Adrian