| 

.NET C# Java Javascript Exception

2
Hallo,

ich bin .NET-Entwickler und kämpfe zur Zeit ein wenig mit Java.
Ich habe 2 Fragen zu Exceptions.
Im unteren Beispiel möchte ich, dass eine Methode eine Exception wirft.

1. Muss ich das "throws Exception" im Methodenkopf zwangsläufig immer angeben wenn eine
Methode eine Exception wirft?
2. Wenn ich das "throws Exception" im Methodenkopf schreibe, ist anscheinend
der Aufrufer der Methode gezwungen den Methoden-Aufruf in ein try/catch zu schachteln.

Ist das wirklich so krass unterschiedlich zu .NET?
Sobald eine Methode eine Exception wirft, zieht diese ja einen Rattenschwanz an
Folgen nach sich...

public int Berechnung(int z1, int z2) throws Exception
{
if (z1==0)
{
throw new Exception("Z1 darf nicht Null sein");
}

return z1+z2;
}


Danke und viele Grüße

Kevin
News:
14.08.2014
Kevin_1978 11 2
1 Antwort
4
Java unterscheidet zwischen geprüften Ausnahmen (checked exceptions) und ungeprüften Ausnahmen (unchecked exceptions). Letztere sind alle Klassen, die direkt oder indirekt von RuntimeException ableiten (und natürlich RuntimeException selbst), und verhalten sich in etwa so wie Ausnahmen in .NET. Alle anderen Exception-Klassen sind geprüfte Ausnahmen, und für diese gilt das von Dir beschriebene Verhalten - Du mußt sie deklarieren oder fangen.

Die Java-Erfinder wollten damit wohl erreichen, daß der Nutzer einer Methode sich auch Gedanken darüber macht, was schief gehen kann, und entsprechend Vorsorge trifft. Das Problem ist aber, dass es sehr lange gedauert hat, bis man in der Java-Welt verstanden hat, wann es sinnvoll ist geprüfte Ausnahmen zu verwenden und wann nicht. Ich würde noch nicht mal behaupten, daß es da bis heute ein allgemeines Einverständnis darüber gibt. Entsprechend finden sich in vielen Bibliotheken und wohl sogar im JDK selbst auch Beispiel, wie man es nicht machen soll. Eine nach meiner Einschätzung aber inzwischen weit verbreitete Regel ist: Eine geprüfte Ausnahme sollte eine Situation darstellen, mit der der Aufrufer tatsächlich etwas anfangen kann, wo er eine Chance hat zu reagieren, die prinzipiell vorhersehbar ist und die zur fachlichen Domäne der jeweiligen Methode gehört.

Beispiele:

  • Der Konstruktor von FileInputStream kann eine FileNotFoundException werfen. Das ist eine geprüfte Ausnahme und ist in dem Fall auch gut so: der Aufrufer weiß, daß er es mit Dateien zu tun hat und daß er sich mit dem Fall beschäftigen muß, daß die evtl. nicht da sind. Selbst wenn er unmittelbar vor dem Aufruf noch die Existenz geprüft hat, könnte es sein, daß irgendein anderer Prozess sie zwischen Prüfung und Zugriffsversuch gelöscht hat. Er muß also mit dieser Situation rechnen, trotzdem stellt sie eine Ausnahme dar. Er ist prinzipiell in der Lage, zu entscheiden, was passieren soll.
  • Schlecht wäre es, wenn eine Klasse, für die die Verwendung einer Datei ein Implementierungsgeheimnis ist, eine FileNotFoundException nach außen weiterreicht, weil der Entwickler zu faul war, sie zu behandeln. Stell Dir eine Klasse mit Mathefunktionen vor, die auf Logarithmen-Tabellen zugreift, die als Dateien vorliegen. Was soll ein Aufrufer einer Mathefunktion mit einer FileNotFoundException anfangen? Er hat keine Chance, irgendwie sinnvoll darauf zu reagieren. Außerdem wird durch die Deklaration der Exception ein Implementierungsgeheimnis nach außen sichtbar. So etwas ist also zu vermeiden - wenn es keine bessere Lösung gibt, dann durch Wrappen in einer RuntimeException.
  • Die NullPointerException ist von RuntimeException abgeleitet und somit eine ungeprüfte Ausnahme. Alles andere wäre auch kompletter Blödsinn, denn diese Situation ist nie vorhersehbar und auch nicht behandelbar - sie bedeutet einfach nur: das Modul ist kaputt.
  • IllegalArgumentException ist auch eine ungeprüfte Ausnahme und wäre die richtige Exception für Dein Beispiel (vorausgesetzt, Du hast dokumentiert, daß z1 nicht null sein darf). Der Programmierer, der die Methode Berechnung (nach Java-Konvention übrigens kleingeschrieben: berechnung, oder noch besser: berechne) aufruft, weiß, welche Parameter gültig sind. Wenn man ihn zwingt, die IllegalArgumentException zu behandeln, könnte er dort nur Code hineinschreiben, den er prinzipiell auch schon vor Aufruf der Methode hätte ausführen können. Das bringt also auch nichts, deshalb ist diese Exception zu Recht eine RuntimeException.


Es ist aus dieser Perspektive so gut wie nie eine gute Idee, "throw new Exception()" oder "throws Exception" zu schreiben.
15.08.2014
Matthias Hlawatsch 13,2k 4 9

Stelle deine Java-Frage jetzt!