Java Exceptions - wann sinnvoll?

cl0udt

Lt. Junior Grade
Registriert
Sep. 2008
Beiträge
508
Hi Leute,

hab mittlerweile großen gefallen an Exceptions in Java gefunden.
Allerdings verleitet mich das auch sehr, sie an jeder Stelle einzusetzen.
Ich frage mich allerdings, ob das so sinnvoll ist.
Gibt es eine Faustregel von euch Java-Profis, wann man eine Exception "werfen" sollte und wann es nutzlos bzw. übertrieben ist?

Als Beispiel:

Eine Methode bekommt einen Stelle in einem vorhandenen Array übergeben, an die z.b. das Wort "Auto" gesetzt werden soll. Wenn jetzt jemand an der Stelle -1 das Wort haben möchte, wie behandle ich sowas am besten? Da wird ja z.b. vom Objekt Array sowieso schon ne Exception geworfen. Catche ich die dann in meiner Methode, oder überprüf ich lieber, dass keine negativen Zahlen eingegeben werden dürfen und schmeiß dann selbst ne neue Exception? Oder einfach nur ne Fehlermeldung via syserr und ignoriere die Eìngabe?

Gut, ich denke das kommt ganz drauf an, was man haben will, aber wie würdet ihr das am sinnvollsten machen?

Danke schonmal!
 
Geile Frage. ;-) Naja, kurz gefasst: Da gibt es sehr viele unterschiedliche Meinungen zu. Du kommst nicht herum, dich in eine sehr intensiv und sehr lang geführte Diskussion einzulesen:

http://www.ibm.com/developerworks/java/library/j-jtp05254.html
http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html
http://today.java.net/pub/a/today/2006/04/06/exception-handling-antipatterns.html
http://www.octopull.demon.co.uk/java/ExceptionalJava.html

...

Kurz um: Halt es so, wie du es für dich richtig findest. Bei mir kommt es immer auf die Anwendung an. Wenn ich eine sehr komplexe Anwendung mit sehr vielen Fehlerquellen (insb. bei vielen Input- und Output-Sources) habe, dann benutze ich sehr viele Exceptions. Du ersparst dir sehr viel Ärger, Mühe und Kummer damit. Bei Kleinigkeiten, typisch linearen zweihundert-Zeilen-Codes, verzichte ich weitestgehend drauf.
 
Die Antwort ist "immer".

Protokollierung, Interaktion mit dem Benutzer ist das A und O.

Denk nur mal dran du bekommst ein leeres Bild und keine Fehlermeldung? Ja, nicht schlimm!

Ich bekomme ein leeres Bild und ein Fehler kommt? Support!

Btw: Durch die Fehler grenzt du auch das Debugging enorm ein. Bei großen Programmen wirst du also nicht rum kommen.
 
tach,

zum bsp: einfach die exception nehmen die es schon gibt, außer du möchtest sie selber behandeln.
1. grundsätzlich, meiner meinung nach, exceptions vermeiden, ich weiß nich wie schnell diese in java behandelt werden, da eh fast alles mit exceptions abgefangen wird, bzw vieles, aber bei c++ zB sind exceptions extrem langsam im vergleich zu einer einfachen wertrückgabe.
2. exceptions sind meist einfacher zu schreiben und einfacher zu durchdenken als andere fehlerbehandlungsmethoden.
3. exceptions nur bei größeren problemen verwenden, heißt nicht bei problemen die öfter auftreten können, wobei es wie gesagt in java meist gar nicht anders möglich ist

evtl kann dir jemand dazu noch mehr sagen hab jetzt noch nich soviel mit java gemacht.

mfg
 
Ich wuerde es ueberpruefen und keine Falscheingaben zulassen. Wenn doch eine Falscheingabe erfolgt, muss das dem User kommuniziert werden.

Wenn du an dieser Stelle eine Ex wirfst, musst du diese an anderer Stelle ja auch wieder behandeln, also kannst du es dann auch gleich dort tun.

if(Eingabe = korrekt) {
...
} else {
logger.error("Falsche Eingabe: " + Eingabe);
weitere Schritte um dem User das mitzuteilen, je nach Implementierung deiner Software
}

EDIT: Ex machen dann Sinn, wenn die Abarbeitung einer Methode unterbrochen werden soll und nachfolgender Code Unsinn produzieren wuerde.

Du baust dir dann die Methode tuWasTolles() throws IrgendwasException {
...
im FehlerFall throw new IrgendwasException("Boeser Fehler aufgetreten");
}

Jetzt kann diese Methode nur in einem try/catch ausgefuehrt werden in dem du dann IrgendwasException faengst und behandelst.


MfG SaxnPaule
 
Zuletzt bearbeitet:
Ich würde sagen es kommt auch sehr auf das verhalten des Programmes an.
Wenn du z.B. eine eigene Libary schreibst sind exceptions durchaus sinnvoll, denn so kann jeder (auch du) der sie verwendet sehen das hier fehler auftreten können und diese entsprechend behandeln. Wenn es aber so trivale fehler sind wie "Bitte geben sie keine Negative Zahl ein" reicht es wenn eine Fehlermeldung ausgegeben wird. Wenn aber z.b. datenstruckturen bearbeitet werden müssen etc. ist es gut wenn man bei dem Versuch im Index -1 zu speichern eine Exception um die Ohren geschmissen bekommt.
 
Immer? Nein! Eine Exception zu fangen erfordert vom System eine Menge Ressourcen und Zeit. Eine einfache Prüfung, ob ein Wert null ist ist deutlich schneller abgearbeitet als drauf zuzugreifen und die Nullrefference-Exception zu behandeln. Natürlich muss man ein globales Exceptionhandling implemnetieren. Die Anwendung darf nicht einfach abrauchen ohne zu sagen was passiert ist. Aber wegen jedem Zugriff oder Operation auf jedes beliebige Objekt immer gleich eine Exception zu fangen ist mit Kanonen auf Spatzen geschossen.
 
dann wurde es falsch verstanden. Ich will damit sagen, dass er die Exceptions (sollten sie geschmissen werden) auch behandeln soll. Schließlich kann ich die auch einfach weiterreichen und das ist nicht zweckmäßig. ;-)
 
Hmm ok, dachte mir schon, dass die Meinungen da sehr weit auseinandergehen.

Also wenn exceptions so viel mehr Ressourcen in Anspruch nehmen als eine einfache Überprüfung, ob ein Wert negativ ist, dann wäre es ja gerade bei größeren Programmierprojekten keine gute idee, die an jeder Stelle zu schmeißen.

Ok, werde dann wohl bei trivialen Problemen eher auf eine normale Fehlermeldung zurückgreifen. Ich habe auch mal gelesen, dass Exceptions, wenn man schon eine werfe, immer behandelt werden sollten, da es sonst keinen Sinn macht. In meinem Beispiel mit dem Array, würde ja einfach nichts gemacht werden...dann ergäbe es da wohl keinen großen sinn, eine exception zu werfen.

EDIT: @Robin.Genau, so kenne ich das auch, dass exceptions immer behandelt werden sollten, wenn man welche wirft :)
 
Ich schließe mich 2fastHunter an. Es kommt sehr darauf an, was für eine Anwendung Du schreiben möchtest.

Die Faustregel besagt, in Libraries werden grundsätzlich keine Exceptions behandelt. Höchstens wird eine Exception in einer kritischen Methode geworfen bzw. in Java deren Behandlung im aufrufenden Code erzwungen. In allen anderen Anwendungsarten gilt, daß man Exceptions "hochbubblen" läßt. Das heißt, im Zweifelsfall hat man nur in der Main-Methode ein Exception-Handling. Die den Fehler verursachende Methode findet man dann über den Stack-Trace.

Es gibt natürlich auch Ausnahmen zu diesen Regeln.
 
Ich bin der Meinung (wie auch Stefan-, Mercsen und 2fastHunter), dass das ein Aspekt des Anwendungsdesigns ist. Darüber hinaus kommt es darauf an was für eine Applikation du baust und was für Frameworks du zusätzlich einsetzt. Manche Frameworks arbeiten z.b. mehr mit Exceptions, um bestimmte Dinge zu triggern.

Bin übrigens der Meinung, dass Weiterreichen/Hochwerfen durchaus in vielen Kontexten Sinn macht. Beispiel: Du hast eine abstrakte Methode in deren Implementierung eine Exception fliegen soll, je nach Aufruf, in verschiedenen Klassen behandelt werden soll. Dasselbe gilt für Interfaces. Spätestens wenn deine Applikation verschiedene Layer hat (z.B. fachlich/technisch oder GUI/Controller/Persistenz etc.) macht es Sinn Exceptions zu werfen.

Die Diskussion über Sinn/Unsinn von Exceptions kann man wirklich ewig führen :)
 
Zuletzt bearbeitet: (Rechtschreibfehler)
Ok, als Fazit nehme ich mit, dass ich Exceptions nur werfe, wenn unbedingt nötig und vor allen Dingen, wenn ich sie auch behandle. Bei trivialen Eingabefehler oder ähnlichem reicht auch eine einfache Fehlermeldung und die Überprüfung ohne trycatch spart Ressourcen.
Das mit dem nach oben "bubblen" lassen der Exceptions muss ich mir mal anschauen, vll macht das Sinn bei meinem Code.

Wenn ich jetzt normale Fehlermeldungen nehme, dann kann ich aber in JUnit-Tests weder mit trycatch prüfen, ob ein Fehler kommt, noch mit AsserEquals...gibts da bei einfachen Fehlermeldungen denn dann auch was geeignetes?
 
Meine Kenntnisse in Java sind leider etwas eingerostet (aktuell C#), aber wieso soll das "Assert" nicht funktionieren? Hast Du das schon mal ausprobiert?
 
Neue JUnit-Test können Exceptions als Asserts, welches dann wie folgt aussieht:
@Test(expected=Exception.class)
public void testCase1() {
throw new Exception("Error");
)

eine Methode für noch ältere JUnit-Bibliotheken ist folgende:
public void testCase1() {
try{
throw new Exception("Error");
fail("Fehler: Exception wurde nicht geworfen!");
}
catch(Exceptione){}
)
 
Ich würde Exceptions dann werfen lassen, wenn ein Fehler auftritt, der sich nicht an Ort und Stelle beheben lässt. Man würde die Eigenschaft des Hochpropagierens ausnutzen.
 
@e-Laurin
Ja, so werd ichs auch handhaben von nun an.

@Bauergiesen
Ich meinte eher, wie man in JUnit normale Fehlermeldungen von syserr testen kann.
Wenn ich jetzt keine Exception schmeiße, soll halt trotzdem ein syserr ausgegeben werden...wird nicht gehen, oder?
 
Ich liste mal ein paar Regeln auf, die ich mir selbst auferlege.


1. Die Anwendung muss auf oberster Ebene immer alle Exceptions abfangen.

So werden alle nicht behandelten Laufzeitfehler abgefangen. Der User bekommt eine entsprechende Fehlernachricht und der Stacktrace des Fehlers kommt ins Logfile.


2. Exceptions NIEMALS mit catch fangen und kommentarlos weitermachen als wäre nichts passiert.

Ein Fehler der nicht bemerkt oder dokumentiert wird kann eine tickende Zeitbombem sein. Im allermildesten Fall schreibt man mindestens einen WARN-Logmessage.


3. Exceptions grundsätzlich nur werfen, wenn eine echte Ausnahmesituation vorliegt.

Eine Ausnahmesituation ist nur dann gegeben, wenn etwas passiert, was definitiv nicht vorgesehen war.

Beispiel: Ein User soll eine Zahl eingeben, gibt aber Buchstaben ein. Das ist zwar ein Fehler, dieser ist aber vorhersehbar und auch zu erwarten -> Keine Exception, sondern explizite Eingabeprüfung und Fehlerbehandlung


4. Exceptions NIEMALS zur Flußkontrolle verwenden.

Ein Algorithmus, welcher durch Exceptions gesteuert wird macht zukünfitge Wartung/Refaktorierungen am Code sehr schwierig.


5. Bibliotheken haben eine eigene Exceptionklasse.

Schreibt man eine Bibliothek, dann sollte man eine eigene Exceptionklasse schreiben, welche entsprechende Details über den Fehler enthält. So kann dann die nutzende Anwendung entsprechend reagieren.

Gerade bei Mehrschichtarchitekturen macht es sinn, wenn man Exceptions an Modulgrenzen fängt, in einer neuer Exception (mit entsprechend mehr infos über den Vorgang) verpackt und weiter nach oben wirft.

Es hilft im Nachhinein sehr den Kontext des Fehlers schneller zu verstehen.


6. Threads, welche sich regelmäßig ausführen, sollte man mit einem Try catch schützen, damit der Thread nicht stirbt.

Angenommen man hat einen Thread, welcher regelmäßig eine URL abfragt um neue Daten zu erhalten. Dieser Thread sollte nicht gleich sterben, nur, weil vllt. das Netz kurz weg war.
 
e-Laurin schrieb:
Ich würde Exceptions dann werfen lassen, wenn ein Fehler auftritt, der sich nicht an Ort und Stelle beheben lässt.
Absolut richtig! Konsequenterweise sollte man Exceptions auch erst dann behandeln, wenn man den Fehler sinnvoll behandeln kann. Wenn ich mit einen Fehler in der übergeordneten Methode nichts anfangen kann sollte man die Exception einfach weiterwerfen. Im Extremfall greift dann eben das globale Exception-Handling, aber dafür ist es ja da.
 
Zurück
Oben