Betrachten wir die Situation, in der Sie den bereitgestellten Code haben:
public void delete() throws IOException, SQLException { // Non-Compliant
/* ... */
}
Hier besteht die Gefahr, dass der Code, den Sie aufrufen delete()
, wie folgt aussieht:
try {
foo.delete()
} catch (Exception e) {
/* ... */
}
Das ist auch schlimm. Und es wird mit einer anderen Regel abgefangen, die das Abfangen der Basis-Exception-Klasse kennzeichnet.
Der Schlüssel ist, keinen Code zu schreiben, der Sie dazu bringt, schlechten Code anderswo zu schreiben.
Die Regel, auf die Sie stoßen, ist ziemlich verbreitet. Checkstyle hat es in seinen Designregeln:
ThrowsCount
Beschränkt die Anzahl der Auslöseanweisungen auf einen bestimmten Wert (standardmäßig 1).
Begründung: Ausnahmen sind Teil der Schnittstelle einer Methode. Das Deklarieren einer Methode zum Auslösen zu vieler unterschiedlich verwurzelter Ausnahmen macht die Ausnahmebehandlung lästig und führt zu schlechten Programmierpraktiken wie dem Schreiben von Code wie catch (Ausnahme ex). Diese Prüfung zwingt Entwickler dazu, Ausnahmen in eine Hierarchie zu setzen, sodass im einfachsten Fall nur ein Ausnahmetyp von einem Aufrufer geprüft werden muss, aber bei Bedarf auch alle Unterklassen speziell abgefangen werden können.
Dies beschreibt genau das Problem und was das Problem ist und warum Sie es nicht tun sollten. Es ist ein anerkannter Standard, den viele statische Analysewerkzeuge identifizieren und kennzeichnen.
Und während Sie können es nach Sprache Design tun, und es kann vorkommen, dass es das Richtige ist, zu tun , ist es etwas , das Sie sehen sollen und sofort gehen „um, warum mache ich das?“ Es mag für internen Code akzeptabel sein, bei dem jeder diszipliniert genug ist, um nie catch (Exception e) {}
etwas zu tun , aber in den meisten Fällen habe ich Leute gesehen, die vor allem in internen Situationen Abstriche gemacht haben.
Lassen Sie die Teilnehmer Ihrer Klasse keinen schlechten Code schreiben.
Ich möchte darauf hinweisen, dass dies mit Java SE 7 und höher weniger wichtig ist, da mit einer einzelnen catch-Anweisung mehrere Ausnahmen abgefangen werden können (Abfangen mehrerer Ausnahmetypen und erneutes Auslösen von Ausnahmen mit verbesserter Typprüfung von Oracle).
Mit Java 6 und früher hatten Sie Code, der so aussah:
public void delete() throws IOException, SQLException {
/* ... */
}
und
try {
foo.delete()
} catch (IOException ex) {
logger.log(ex);
throw ex;
} catch (SQLException ex) {
logger.log(ex);
throw ex;
}
oder
try {
foo.delete()
} catch (Exception ex) {
logger.log(ex);
throw ex;
}
Keine dieser Optionen mit Java 6 ist ideal. Der erste Ansatz verletzt DRY . Mehrere Blöcke tun immer wieder dasselbe - einmal für jede Ausnahme. Sie möchten die Ausnahme protokollieren und erneut auslösen? Okay. Dieselben Codezeilen für jede Ausnahme.
Die zweite Option ist aus mehreren Gründen schlechter. Erstens bedeutet dies, dass Sie alle Ausnahmen abfangen. Der Nullzeiger wird dort abgefangen (und sollte es auch nicht). Darüber hinaus werfen Sie einen erneut aus, Exception
was bedeutet, dass die Methodensignatur deleteSomething() throws Exception
eine weitere Verwirrung verursacht, da Benutzer Ihres Codes nun gezwungen sind, diesen zu verwenden catch(Exception e)
.
In Java 7 ist dies nicht so wichtig, da Sie stattdessen Folgendes tun können:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
Darüber hinaus ist die Art zu überprüfen , ob man nicht die Typen der Ausnahmen fängt geworfen werden:
public void rethrowException(String exceptionName)
throws IOException, SQLException {
try {
foo.delete();
} catch (Exception e) {
throw e;
}
}
Die Typprüfung erkennt, dass es sich e
möglicherweise nur um Typen IOException
oder handelt SQLException
. Ich bin immer noch nicht sonderlich begeistert von der Verwendung dieses Stils, aber es verursacht nicht so schlechten Code wie unter Java 6 (wo es Sie zwingen würde, die Methodensignatur als die Superklasse zu haben, die die Ausnahmen erweitern).
Trotz all dieser Änderungen erzwingen viele statische Analysetools (Sonar, PMD, Checkstyle) immer noch Java 6-Stilrichtlinien. Es ist keine schlechte Sache. Ich bin mit einer Warnung einverstanden, dass diese noch durchgesetzt werden sollen, aber Sie können die Priorität für sie in Dur oder Moll ändern, je nachdem, wie Ihr Team sie priorisiert.
Wenn Ausnahmen aktiviert oder deaktiviert werden sollen ... das ist eine Frage der g r e eine t Debatte , dass man leicht unzählige Blog - Beiträge Aufnahme jede Seite des Arguments finden. Wenn Sie jedoch mit aktivierten Ausnahmen arbeiten, sollten Sie wahrscheinlich vermeiden, mehrere Typen zu werfen, zumindest unter Java 6.