117 Stimmen

Ist es eine schlechte Praxis, Throwable zu fangen?

Ist es eine schlechte Praxis, sich Throwable ?

Zum Beispiel etwas in der Art:

try {
    // Some code
} catch(Throwable e) {
    // handle the exception
}

Ist dies eine schlechte Praxis oder sollten wir so spezifisch wie möglich sein?

111voto

BalusC Punkte 1034465

Sie müssen so genau wie möglich sein. Sonst könnten sich auf diese Weise unvorhergesehene Fehler einschleichen.

Außerdem, Throwable deckt Error auch und das ist in der Regel kein Punkt der Rückkehr . Sie wollen das nicht abfangen/behandeln, Sie wollen, dass Ihr Programm sofort stirbt, damit Sie es richtig reparieren können.

39voto

Brandon Yarbrough Punkte 34849

Das ist eine schlechte Idee. In der Tat, sogar fangen Exception ist in der Regel eine schlechte Idee. Lassen Sie uns ein Beispiel betrachten:

try {
    inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(Throwable e) {
    inputNumber = 10; //Default, user did not enter valid number
}

Nehmen wir an, getUserInput() blockiert eine Weile, und ein anderer Thread hält Ihren Thread auf die denkbar schlechteste Weise an (er ruft thread.stop() auf). Ihr catch-Block fängt eine ThreadDeath Fehler. Das ist super schlecht. Das Verhalten Ihres Codes nach dem Abfangen dieser Exception ist weitgehend undefiniert.

Ein ähnliches Problem tritt beim Abfangen von Ausnahmen auf. Vielleicht getUserInput() scheiterte aufgrund einer InterruptException oder einer permission denied exception beim Versuch, die Ergebnisse zu protokollieren, oder aufgrund aller möglichen anderen Fehler. Sie haben keine Ahnung, was schief gelaufen ist, und deshalb wissen Sie auch nicht, wie Sie das Problem beheben können.

Sie haben drei bessere Möglichkeiten:

1 - Fangen Sie genau die Ausnahme(n) ab, mit denen Sie umgehen können:

try {
    inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(ParseException e) {
    inputNumber = 10; //Default, user did not enter valid number
}

2 - Werfen Sie jede Ausnahme, auf die Sie stoßen und mit der Sie nicht umgehen können, zurück:

try {
    doSomethingMysterious();
} catch(Exception e) {
    log.error("Oh man, something bad and mysterious happened",e);
    throw e;
}

3 - Verwenden Sie einen endgültigen Block, damit Sie nicht daran denken müssen, erneut zu werfen:

 Resources r = null;
 try {
      r = allocateSomeResources();
      doSomething(r);
 } finally {
     if(r!=null) cleanUpResources(r);
 }

22voto

gawi Punkte 13510

Beachten Sie auch, dass Sie, wenn Sie Throwable können Sie auch fangen InterruptedException die eine besondere Behandlung erfordert. Siehe Umgang mit InterruptedException für weitere Einzelheiten.

Wenn Sie nur ungeprüfte Ausnahmen abfangen wollen, können Sie auch dieses Muster verwenden

try {
   ...
} catch (RuntimeException exception) {
  //do something
} catch (Error error) {
  //do something
}

Wenn Sie also Ihren Code ändern und einen Methodenaufruf hinzufügen, der eine geprüfte Ausnahme auslösen kann, wird der Compiler Sie daran erinnern, und Sie können dann entscheiden, was in diesem Fall zu tun ist.

16voto

Andrew Norman Punkte 763

Direkt aus der Javadoc der Klasse Error (die empfiehlt, diese nicht zu fangen):

 * An <code>Error</code> is a subclass of <code>Throwable</code> 
 * that indicates serious problems that a reasonable application 
 * should not try to catch. Most such errors are abnormal conditions. 
 * The <code>ThreadDeath</code> error, though a "normal" condition,
 * is also a subclass of <code>Error</code> because most applications
 * should not try to catch it. 

 * A method is not required to declare in its <code>throws</code> 
 * clause any subclasses of <code>Error</code> that might be thrown 
 * during the execution of the method but not caught, since these 
 * errors are abnormal conditions that should never occur. 
 *
 * @author  Frank Yellin
 * @version %I%, %G%
 * @see     java.lang.ThreadDeath
 * @since   JDK1.0

13voto

DNA Punkte 40967

Catching Throwable ist manchmal notwendig, wenn Sie Bibliotheken verwenden, die Fehler übermäßig enthusiastisch werfen, sonst kann Ihre Bibliothek Ihre Anwendung beenden.

Unter diesen Umständen wäre es jedoch am besten, nur die spezifischen Fehler anzugeben, die von der Bibliothek ausgelöst werden, und nicht alle Throwables.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X