[Stil] Exceptions in der Klasse behandeln oder throwen?

Status
Nicht offen für weitere Antworten.

Hutmacher

Bekanntes Mitglied
Nehmen wir an, wir haben die Klasse VogelReader, mit der man Dateien des Typs .vogel auslesen kann. Diese Klasse besitzt einen konventionellen Konstruktor, dem man einen String als Pathname übergibt.
Sie wirft, sofern die Datei nicht gefunden wurde, eine IOException.
Jetzt ist die Frage: Wo soll die gecatcht werden?

Variante 1:
Java:
packe com.wayne.util;

import java.io.IOException;

public class VogelReader
{
    private String pathname;

    public VogelReader(String pathname)
     throws IOException
    {
        if ( doesNotExist(pathname) )
        {
            throw new IOException;
        }

        this.pathname = pathname;
    }

    //and-so-on-methods
}

//MainClass.java
public class MainClass
{
    public static void main(String[] args)
    {
        try
        {
            VogelReader vR = new VogelReader("gibbetsnich.vogel");
        }
        catch (IOException ioe)
        { 
            System.out.println("Die Datei existiert nicht!");
        }
    }
}
Hier wird in der Main-Methode gecatcht.
Vorteile:
Der Code ist flexibler. Die VogelReader-Klasse kann auch woanders noch verwendet werden. Es kann immer nach Bedürfnissen eine Fehlermeldung angepasst werden, oder sie kann direkt an die GUI weitergeleitet werden. Das wäre OOP, da Wiederverwendung.
Nachteile:
Der Code in der Main-Klasse (oder in anderen Klassen) hat immer einen try-catch-Block am Hals. Das stört mMn den Lesefluss erheblich, vor allem dann, wenn es mehrere Klassen gibt, die teilweise auch noch gleiche Exception werfen. Dann braucht man mehrere Blöcke.

Variante 2:
Java:
packe com.wayne.util;

import java.io.IOException;

public class VogelReader
{
    private String pathname;

    public VogelReader(String pathname)
    {
        if ( doesNotExist(pathname) )
        {
            System.out.println("Die Datei existiert nicht!");
        }
        else
        {
            this.pathname = pathname;
        }
    }

    //and-so-on-methods
}

//MainClass.java
public class MainClass
{
    public static void main(String[] args)
    {
        VogelReader vR = new VogelReader("gibbetnich.vogel");
    }
}
Hier wird in der Klasse itself direkt gecatcht.
Vorteile:
Der Main-Code ist klar lesbar und nicht von aufdränglichen try-catch-Blöcken zugeballert oder überhäuft. Wenn man diese Code liest, weiß man, dass man sich gar nicht mehr um das Catchen in irgendeiner Weise braucht, sondern dass es automatisch erfolgt. Das wäre OOP, da die Komplexität verringert wird, also Abstraktion.
Nachteile:
Die Wiederverwendbarkeit sinkt stark, da nun die Fehlermeldungen nicht mehr den entsprechenden Bedürfnissen angepasst werden oder in eine GUI-Ausgabe umgeleitet werden können.

Was denkt ihr darüber? Was ist besserer Codestil?
 
Zuletzt bearbeitet:

mvitz

Top Contributor
Ich würde auch Variante 1 nehmen.

Allerdings finde ich dann die IOException hier falsch. Solltest lieber eine VogelNotFoundException erstellen und werfen (diese kannst du dann auch von RuntimeException ableiten und somit muss man nicht try/catchen in der Main.
 

Painii

Bekanntes Mitglied
Generell würd ich sagen:
Logik behandelt keine Exceptions ( in dem Sinne von System.out.println).
Weil:
Wirft der Konstruktor eine Exception wird kein Object erstellt.
Behandelst du die Exception nicht richtig im Konstruktor, dann wird bei dir pathname==null sein und dir später wahrscheinlich auch eine NullPointerException werfen weil der Konstruktor nicht alles initialisiert hat.


Was anderes wäre es wenn dein Konstruktor wenn es die Datei nicht gibt einfach eine neue Datei versucht zu erzeugen mit dem Namen - da könnte man die Exception direkt da behandeln, denn danach wäre pathname auch wieder in einem sinnvollen Zustand.
 

tfa

Top Contributor
Warum keine FileNotFoundException?

Wenn man sich selber zwingen will, die Exception sofort zu behandeln, wäre FileNotFoundException die beste Wahl. Andernfalls ist eine eigene RuntimeException sinnvoll (wenn diese Ausnahme etwa nicht behoben werden kann).
Variante 2 ist jedenfalls schlecht. Kaputtes Design.
 

mvitz

Top Contributor
Warum keine FileNotFoundException?

Naja, kommt vermutlich doch noch mehr auf die genau Aufgabe der Klasse an.

Aber wenn ich einen Vogel laden möchte (was die Klasse ja vermutlich machen soll). Dann sollte den Aufrufer eigentlich nicht interessieren, woher der Vogel geladen wird (File, Dynamisch erzeugt, ...), zumal der Aufrufer dass ja sowieso nicht beheben kann. Mann kann ja dann die IOException/FileNotFoundException immer noch mitwerfen, bzw. in der Exceptionmessage darauf hinweisen.
 
M

maki

Gast
Würde da zu einer IllegalArgumentException tendieren, ist sowiso schon eine RuntimeException.
Eine checked Exception würde ich vermeiden.
 

schalentier

Gesperrter Benutzer
Also habis Argumentation kann ich folgen, aber trotzdem besteht die Gefahr, dass es frueher oder spaeter pro Klasse eine oder mehrere Exceptions gibt... ich hab da schon ungeheuerliches gesehen (VogelNotFoundException, VogelTooBigException, VogelInvalidStateException, ...).

Warum keine checked Exception? Warum keine IOException?
Also spontan wuerde ich mich fuer Variante 1 entscheiden, allerdings in der Main-Methode die Exception nicht fangen, sondern einfach weiterwerfen.
 
M

maki

Gast
Warum keine checked Exception? Warum keine IOException?
Checked Eceptions zwingen den Aufrufer, entweder die Exception zu behandeln oder weiterzuwerfen.
Ob das behandeln bzw. das weiterwerfen Sinn macht, ist eine Sache des Anwedungsfalles.
Wenn ich nicht garantieren kann dass die Exception sinnvoll behandelt werden kann, vermeide ich checked Exceptions, und leider gibt es so gut wie nie den Fall das man Garantieren kann dass der Aufrufer etwas wirklich sinnvolles mit der Gefangenen Exception anstellen kann.

Also spontan wuerde ich mich fuer Variante 1 entscheiden, allerdings in der Main-Methode die Exception nicht fangen, sondern einfach weiterwerfen.
Tja, das wäre ja auch kein sinnvoller Weg um die gefangene Exception zu behandeln, wenn diese in der Main weitergeworfen würde, kann man sie auch gleich als unchecked Exception behandeln.
Das Ergebnis ist dasselbe, aber ohne sinnlose try/catch Blöcke und throws Klauseln ;)
Weniger Code -> selbes Ergebnis

Das ist eigentlich das Grundproblem mit checked Exceptions.
 

schalentier

Gesperrter Benutzer
Ich glaube wir vermischen hier zwei Probleme:

- Exceptionhandling: Also wie genau handhabt meine Anwendung evtl. auftretende Exception (ob checked oder unchecked is erstmal egal). In einem Test oder einer simplen Testanwendung (so fasse ich das Beispiel auf) wuerd ich ueberhaupt keine Exceptions fangen... wenn eine Auftritt sehe ich (als Entwickler) den Stacktrace und kann dann die Ursache beheben. In einer richtigen Anwendung wuerde ich einen zentralen Exceptionhandle-Mechanismus einbauen, d.h. in der Mainklasse oder im Dispatcher oder sonstwo ein:
Code:
try {
   new Starter().start();
} catch( Error error ) {
   handleError( error );
}
Dort landen dann alle bisher nicht sinnvoll verarbeiteten Exceptions und werden, z.B. in einem Fehlerdialog angezeigt (mit SendenAn-Button oder Mailversand an den Support oder nur Log..).

- checked vs unchecked. Hier bin ich mir selbst nicht so sicher, was guenstiger ist. Fuer checked spricht, dass man an einer Methode sofort sieht, dass dort Exceptions fliegen koennen (und welche), um die man sich als Aufrufer entweder kuemmert (falls sinnvoll) oder das eben weiterwirft. Das der Code sich dadurch "aufblaeht" kann man so sehen, aber letztlich kommt doch nur ein "throws IrgendwasException" an die Methodensignatur...

Mh... bin mir selbst unschluessig was den zweiten Punkt angeht... Kennt jemand nen gutes Paper/Blog dazu?
 
M

maki

Gast
Dort landen dann alle bisher nicht sinnvoll verarbeiteten Exceptions und werden, z.B. in einem Fehlerdialog angezeigt (mit SendenAn-Button oder Mailversand an den Support oder nur Log..).
Du machst da eine Annahme die nicht richtig ist: Man kann gar nicht alle Exceptions sinnvoll verarbeiten.
Beispiel: JDBC API
Alles checked Exceptions, führt dann zu so sinnvollen Konstrukten wie try/catch Blöcke in try/catch Blöcken... aber was sollte man denn sinnvolles machen wenn die DB nicht mehr erreichbar ist für eine Serveranwendung? Eine Meldung für den User wie "Sorgen sie dafür, dass die DB wieder verfügbar ist" ist genauso hilfreich wie der Stacktrace.

Die Gefahren durch checked Exceptions sind dagegen sehr deutlich: Programmierfehler werden u.U. verschleiert/verdeckt, wie oft hat man so etwas schon mal gelesen:
Java:
...
try {
...
} catch (Exception ingore) {}
..
Mh... bin mir selbst unschluessig was den zweiten Punkt angeht... Kennt jemand nen gutes Paper/Blog dazu?
Das inet ist voll davon, einfach mal googeln ;)

[JavaSpecialists 162] - Exceptions in Java
[JavaSpecialists 033] - Making Exceptions Unchecked

Kurz: Checked Exceptions sind eine Missgeburt, bis jetzt hat keine andere Sprache diesen Fehler nachgebaut/wiederholt, nicht ohne Grund ;)
 

tfa

Top Contributor
Hier noch mehr davon:
Java's checked exceptions were a mistake (and here's what I would like to do about it)
Bruce Eckel's MindView, Inc: Does Java need Checked Exceptions?
Kurz: Checked Exceptions sind eine Missgeburt, bis jetzt hat keine andere Sprache diesen Fehler nachgebaut/wiederholt, nicht ohne Grund ;)
Seh ich genauso. Die selten Fälle, wo man sie sinnvoll einsetzen kann, sind sehr selten und beschränken sich auf Individualsoftware. In Bibliotheken und APIs haben sie überhaupt nichts zu suchen. Ich ärgere mich fast täglich über irgendwelche RemoteExceptions, SQLExceptions, IOExceptions, Exceptions im Zusammenhang mit Reflection, die ich nicht behandeln kann und will aber muss.
 

schalentier

Gesperrter Benutzer
aber was sollte man denn sinnvolles machen wenn die DB nicht mehr erreichbar ist für eine Serveranwendung? Eine Meldung für den User wie "Sorgen sie dafür, dass die DB wieder verfügbar ist" ist genauso hilfreich wie der Stacktrace.

Naja ne normale Fehlermeldung, "Die Datenbank ist nicht erreichbar, ueberpruefen sie die Netzwerkeinstellungen" waere sicher nicht verkehrt oder? Aber das haengt auch sehr stark von der eigentlichen Anwendung ab. Ich entwickel grad an ner Swing Anwendung, und da sollte doch sowas eingebaut sein, oder nicht?

Zum anderen Thema (un/checked): Okay, geh ich mit. Die Frage waere dann aber, warum soviele (alle?) Frameworks ausgiebig Gebrauch machen von checked Exceptions...
 

musiKk

Top Contributor
Mal noch ein paar Fragen hinterher... Was ist z. B. das Problem an der IOException als checked Exception? Warum soll mein Programm mit einer unchecked Exception abstürzen, wenn dem Nutzer z. B. das Internet wegfällt und ich dadurch eine IOException bekomme, weil ich gerade Daten übers Netz ziehe? Wenn ich nicht weiß, wie ich eine IOException an einer bestimmten Stelle zu behandeln habe, dann werfe ich sie einfach weiter (oder fange im Bedarfsfall und gebe null zurück).
Ich find das gut, ein Stück Code zu haben und sagen zu können, wenn in einem Code-Abschnitt eine (unchecked) Exception kommt, dann ist entweder wirklick der Rechner explodiert oder ich habe einen Programmierfehler gemacht (oder der Programmierer der Lib, die ich benutze... nix schlimmeres, als irgendwelche NPEs, die aus dem Nichts kommen).
Warum kann man nicht sagen, dass man nie festlegen kann, wo reagiert werden soll? Wenn einer eine read()-Methode aufruft, dann kann der auch auf eine IOException reagieren. Irgendwas wird gelesen, irgendwas wird damit gemacht. Wenn ich eine Datei lese, weil ich eine Konfiguration erstellen will, dann kann ich die möglicherweise auftretende IOException oder Syntaxfehler in einer ConfigurationCreationException bündeln, dann kriegt das auch eine semantische Bedeutung. Irgendwo wird eine Konfiguration erwartet, dann kann der auch auf diese Exception reagieren und eine entsprechende Fehlermeldung ausgeben.

Wenn man nur checked Exceptions verwendet, dann verleitet das ja dazu, nirgendwo Behandlungen vorzunehmen (gerade, wenn es heißt "are always fatal") und irgendwo einen Stacktrace hinzuwerfen. Nur das ist ja absolut grausam. Kein Nutzer soll einen Stacktrace sehen, das gehört für mich zu dem, was immer so gerne als "polished" bezeichnet wird. Also fangen wir auf höchster Ebene alle Exceptions, die dann völlig aus dem Kontext gerissen sind, geben einfach nur ein "Es gab einen Fehler, was genau weiß ich auch nicht." aus und beenden das Programm.
 
M

maki

Gast
Mal noch ein paar Fragen hinterher... Was ist z. B. das Problem an der IOException als checked Exception?
Mit einer unchecked Exception hättest du die Wahl ob du die Exception fängst und bearbeitest oder nicht, mit einer checked Exception hast du diese Wahl nicht, egal ob eine mögliche Behandlung sinnvoll ist oder nicht. Mit checked Exceptions bist du also gezwungen, sinnlosen Code zu schreiben(inlkl. Risiko von Fehlern), und das ist sehr oft der Fall.

Warum soll mein Programm mit einer unchecked Exception abstürzen, wenn dem Nutzer z. B. das Internet wegfällt und ich dadurch eine IOException bekomme, weil ich gerade Daten übers Netz ziehe?
Dich hindert doch gar nichts daran eine unchecked Exception zu fangen und zu behandeln.

NPEs haben übrigens fast immer einen Programmierfehler als Ursache, so etwas "sinnvoll" zu behandeln heisst schlicht und ergreifend den Bug korrigieren, und Erfahrungsgemäss werden Bugs die auf Programmierfehlern beruhen nicht so schnell korrigiert wenn sie irgendwo "falsch" behandelt werden.

Denn Rest den du beschreibst kannst du genauso auch mit unchecked Exception behandeln.

Wozu also checked Exceptions?

Nachtrag: Nettes Beispiel mit IOException: http://www.java-forum.org.server659...liessen-unreported-exception-must-caught.html

Ich sag nur Try/catch Block in einem try/catch Block, aber keine Möglichekit sinnvoll mit der Exception umzugehen. Mit unchecked Exceptions wäre das nicht passiert, aber checked Exception zwingen uns zu so einem sinnlosen & hässlichen Konstrukt wie geschachtelte try/catch Blöcke.
 
Zuletzt bearbeitet von einem Moderator:

The_S

Top Contributor
Ein "throws ExceptionXYZ" empfinde ich jetzt nicht als störend. Ist mir ehrlich gesagt auch lieber und nicht so zeitaufwendig wie wenn ich bei jeder Methode nachguck, was die denn unter Umständen für Exceptions werfen könnte, und dann entscheide, ob ich sie abfange oder weiterreiche.
 
B

bygones

Gast
Ein "throws ExceptionXYZ" empfinde ich jetzt nicht als störend. Ist mir ehrlich gesagt auch lieber und nicht so zeitaufwendig wie wenn ich bei jeder Methode nachguck, was die denn unter Umständen für Exceptions werfen könnte, und dann entscheide, ob ich sie abfange oder weiterreiche.
ach ne... wenn du deine exceptions einfach ueber throws weitergibts schiebst du sozusagen den Schwarzen peter einfach an den aufrufer

der darf sich dann mit solchen Konstrukten wie try / catch und das dann noch geschachtelt rumschlagen...
nenene

es gibt zum Glueck seit geraumer Zeit die Einsicht und gute Designs verzichten darauf !

es mag ein minimaler Zeitaufwand sein in die API zu schauen ob eine Exception geschmissen wird, dafuer hat man aber einen besseren, klareren code der wesentlich lesbarer und verwenderfreundlich ist... das gewinnt
 
M

maki

Gast
Ein "throws ExceptionXYZ" empfinde ich jetzt nicht als störend. Ist mir ehrlich gesagt auch lieber und nicht so zeitaufwendig wie wenn ich bei jeder Methode nachguck, was die denn unter Umständen für Exceptions werfen könnte, und dann entscheide, ob ich sie abfange oder weiterreiche.
Neben dem was deathbyaclown sagte, steigt das Risiko dass es unliebsame Abhängigkeiten gibt, denn wenn du nicht willst dass Klassen/Methoden deiner GUI eine HibernateException oder SqlException etc kennt (und damit dann Abhängig von diesen APIs ist), musst du die Exception auch wieder umwandeln/übersetzen ("Exception Translation").

Mich nervt dieses ständige umwandeln von checked Exceptions in unchecked Exception ganz schön, aber schlimmer sind die checked Exceptions.
Mit uncheked Exceptions verliert man nix ausser den Zwang unnötigen Code zu schrieben.
 

tfa

Top Contributor
Neben dem was deathbyaclown sagte, steigt das Risiko dass es unliebsame Abhängigkeiten gibt, denn wenn du nicht willst dass Klassen/Methoden deiner GUI eine HibernateException oder SqlException etc kennt (und damit dann Abhängig von diesen APIs ist), musst du die Exception auch wieder umwandeln/übersetzen ("Exception Translation").

Noch so ein Beispiel ist RMI. Ich wollte mal einen schon vorhandenen Service (definiert über ein einfaches Service-Interface) remote verfügbar machen. Der Einfachheit halber habe ich mich für RMI entschieden. Leider funktionierte das nicht, weil im RMI-Interface sämtliche Methoden die (checked) Exception RemoteException deklarieren müssen. Mein Interface entsprechend zu ändern, ging natürlich ganz und gar nicht. Man hätte an dutzenden Stellen diese Exception auffangen müssen. Ein neues Remote-Interface ableiten klappt auch nicht, da wegen der checked Exception die Methodenprototypen nicht mehr kompatibel wären. Bleibt nur ein Wrapper...

Ein weiteres Problem mit geprüften Ausnahmen ist mir kürzlich aufgefallen. Und zwar beim Unit-Testen.

Java:
public UserProperties(String properties) {
    props = new Properties();
    try {
        this.props.load(new ByteArrayInputStream(properties.getBytes(ENCODING)));
    }
    catch (IOException e) {
        throw new Error(e);
    }
}

Die IOException wird hier niemals fliegen. Zeile 7 wird durch einen Test nie abgearbeitet werden, d.h. eine 100%ige Testabdeckung wird man hier nie erreichen. Das ist zwar nur eine Lapalie, aber trotzdem unschön.
 
Zuletzt bearbeitet:
M

maki

Gast
Die IOException wird hier niemals fliegen. Zeile 7 wird durch einen Test nie abgearbeitet werden, d.h. eine 100%ige Testabdeckung wird man hier nie erreichen. Das ist zwar nur eine Lapalie, aber trotzdem unschön.
Hui, man wird gezwungen Dead-Code zu schreiben :)
 

musiKk

Top Contributor
Dich hindert doch gar nichts daran eine unchecked Exception zu fangen und zu behandeln.

NPEs haben übrigens fast immer einen Programmierfehler als Ursache, so etwas "sinnvoll" zu behandeln heisst schlicht und ergreifend den Bug korrigieren, und Erfahrungsgemäss werden Bugs die auf Programmierfehlern beruhen nicht so schnell korrigiert wenn sie irgendwo "falsch" behandelt werden.

Richtig. Alle unchecked Exceptions sollten Programmierfehler sein. IllegalArgument? Doku nicht richtig gelesen. ArrayIndexOutOfBound? Bereichsprüfung vergessen. NPE? null-Check vergessen, etc.

Die Aufteilung checked -> kann korrigiert oder drauf reagiert werden und unchecked -> sollte nie auftreten und wird daher meist auch nicht gefangen, fand ich eigentlich immer ganz reizvoll. Ein Weiterwerfen würde ich übrigens auch nicht als Behandlung bezeichnen.

Ich verstehe auch nicht so ganz, warum statt unchecked Exceptions nicht Assertions verwendet werden. Die kann man ja vor Programmstart nach Belieben (de)aktivieren. Aber in Java haben die sich ja nicht so recht durchgesetzt. Ist aber ein anderes Thema.

Nachtrag: Nettes Beispiel mit IOException: http://www.java-forum.org.server659...liessen-unreported-exception-must-caught.html

Ich sag nur Try/catch Block in einem try/catch Block, aber keine Möglichekit sinnvoll mit der Exception umzugehen.

Das find ich auch hässlich. Ich habe irgendwo in einem Sun-Tutorial mal folgendes Idiom gesehn:
Java:
void doIOStuff() throws IOException {
	InputStream s = // ...
	try {
		// IO-Kram
	} finally {
		s.close();
	}
}
Ist aber auch nicht so das Gelbe vom Ei.
Nunja, das wars bei mir im Prinzip schon. Ich halte checked Exceptions jetzt nicht für so eine schlimme Missgeburt wie Du, aber ich bin nun auch kein wahnsinniger Verfechter. Ich nehm die Entwicklung weg von den checked Exceptions einfach hin. Immerhin kann man in Java 7 endlich mehrere Exceptions mit dem selben Block behandeln, das hat mich auch immer gestört.
 

Hutmacher

Bekanntes Mitglied
Möchte jemand das alles nochmal konkret zusammenfassen und auf den Punkt bringen und mir dann ein Stück Code zeigen, wie man es denn nun machen sollte?
Irgendwie verliere ich hier den Überblick vor lauter (Un-)Checkern =/
 
M

maki

Gast
Würde das so lösen:
Java:
public class VogelReader {

    private String pathname;
 
    public VogelReader(String pathname) {
        if ( doesNotExist(pathname) ) {
            throw new IllegalArgumentException("Invalid pathname '"+pathname+"'");
        }
 
        this.pathname = pathname;
    }
 
    //and-so-on-methods
}
 
//MainClass.java
public class MainClass
{
    public static void main(String[] args)
    {
            VogelReader vR = new VogelReader("gibbetsnich.vogel");
    }
}
Alles nur imho und ohne Gewähr, der Rechtsweg ist ausgeschlossen ;)
Die Exception sollte natürlich in der JavaDoc zum Konstruktor/Methode dokumentiert sein.

Checked Exceptions wandele ich immer in unchecked Exception um.
 

mvitz

Top Contributor
Und mann kann doch sogar mittlerweile
Java:
public void test() throws RuntimeException;
schreiben, was sogar das Problem der Dokumentation löst.

Edit: und finde maki's Version sehr akzeptabel.
 

tfa

Top Contributor
Und mann kann doch sogar mittlerweile
Java:
public void test() throws RuntimeException;
schreiben, was sogar das Problem der Dokumentation löst.

Das konnte man schon immer. Trotzdem gehört in den JavaDoc-Kommentar, dass und wann diese Exception auftreten kann. Ich glaube das meinte maki (EDIT: Tat er.)
 

mvitz

Top Contributor
Das Problem dabei ist, dass nix in der Doku steht wann die RTE geschmissen wird ;)

Das weißt du bei
Java:
public void test() throws IOException;
ja auch nicht.

RuntimeException stand da nur als Beispiel.

Edit: s.o. ;D
hm irgendwie war mein Gedankengang doof ;)
Die Idee dahinter ist wohl eher:

Wenn man auch RuntimeException mit 'throws ...' deklarieren müsste dann würde das try/catch entfallen und trotzdem wüsste man immer, dass dort Exception x auftreten kann...
 
M

maki

Gast
Dachte dabei eher an so etwas:
Java:
        /**
	 * ...
	 * @throws IllegalArgumentException If the pathname is not an existing path on the filesystem.
	 */
    public VogelReader(String pathname) {
        if ( doesNotExist(pathname) ) {
            throw new IllegalArgumentException("Invalid pathname '"+pathname+"'");
        }
 
        this.pathname = pathname;
    }

Nachtrag: Mögliche Exceptions sollte man eigentlich immer dokumentieren, sonst müssen die nutzer der Methode/Klasse/API entweder den Quelltext lesen oder raten warum sie eine Exception bekommen haben.
 

mvitz

Top Contributor
Ja, nur irgendwo oben war mal gefallen, dass man dann nicht sofort sieht, dass die Methode ne Exception wirft.

Wenn man nun beides (Javadoc + throws) macht, dann zeigt einem die IDE auf jedenfall das throws an, auch wenn die javadoc nicht eingebunden ist.
 

Hutmacher

Bekanntes Mitglied
Dachte dabei eher an so etwas:
Java:
        /**
	 * ...
	 * @throws IllegalArgumentException If the pathname is not an existing path on the filesystem.
	 */
    public VogelReader(String pathname) {
        if ( doesNotExist(pathname) ) {
            throw new IllegalArgumentException("Invalid pathname '"+pathname+"'");
        }
 
        this.pathname = pathname;
    }

Nachtrag: Mögliche Exceptions sollte man eigentlich immer dokumentieren, sonst müssen die nutzer der Methode/Klasse/API entweder den Quelltext lesen oder raten warum sie eine Exception bekommen haben.

Und dies muss nicht mehr abgefangen werden, da keine throws-Deklaration - oder wie? ???:L
 
M

maki

Gast
Und dies muss nicht mehr abgefangen werden, da keine throws-Deklaration - oder wie
Nee,das liegt am Unterschied zwischen checked (Exception) und unchecked (RuntimeException) Exceptions, lies doch mal einen der hier geposteten links ;)
 

ice-breaker

Top Contributor
Das find ich auch hässlich. Ich habe irgendwo in einem Sun-Tutorial mal folgendes Idiom gesehn:
Java:
void doIOStuff() throws IOException {
	InputStream s = // ...
	try {
		// IO-Kram
	} finally {
		s.close();
	}
}
sehr schön, dass es im Tutorial stand, wenn du es nicht machst, wird dir FindBugs den Code um die Ohren hauen :D

nehmen wir folgenden Code:
Java:
void doIOStuff() throws IOException {
	InputStream s = // ...
	try {
		// IO-Kram
		// lange laufende Operationen
		s.close();
	} finally {
		//s.close();
	}
	// 2. lange laufende Operationen
}
würde nun in deinem IO-Kram eine Exception auftreten, die nicht damit zu tun hat, dass der Stream geschlossen wurde, wird der Stream auch die ganze Zeit geöffnet bleiben wie unsere 2. lange Operation läuft, bis der Garbage Collector irgendwann das Objekt als unnütz findet und dabei dann der Stream geschlossen wird: Too many open file descriptors, leak detection
 

musiKk

Top Contributor
Es ging mir dabei eher um try-finally in Verbindung mit throws, statt dem oft anzutreffenden
Java:
void doIOStuff() {
	InputStream s = // ...
	try {
		// IO-Kram
	} catch (IOException x) {
		// blub
	} finally {
		try {
			s.close();
		} catch (IOException x) {
			// what now?
		}
	}
}
 

The_S

Top Contributor
Ich hatte gestern eigentlich noch mehr zu dem Thema geschrieben, aber dann versehentlich den Browser geschlossen und anschließend keine Lust mehr alles noch einmal zu schreiben :oops: .

Nachtrag: Mögliche Exceptions sollte man eigentlich immer dokumentieren, sonst müssen die nutzer der Methode/Klasse/API entweder den Quelltext lesen oder raten warum sie eine Exception bekommen haben.

Deshalb finde ich auch an solchen Stellen RuntimeExceptions nicht so sinnvoll. Ich weiß lieber was geworfen werden kann, als zu raten oder stundenlang API-Doc zu lesen. Dann ruft ne Methode, die RuntimeExceptions wirft ne andere Methode auf, die andere RuntimeExceptions wirft, welche wiederrum eine aufruft, die nochmals andere RuntimeExceptions wirft. Und irgendwo hat nur einer einmal vergessen ne RuntimeException in die Doku zu schreiben bzw. aus der Doku von ner aufrufenden Methode zu übernehmen. Schon ham wir den Salat.

Ganz davon abgesehen, dass bei interner Entwicklung eher weniger (und vor allem nicht während der Entwicklung eines größeren Projekts) eine API-Doc generiert wird, in der man ggf. geworfene RuntimeExceptions nachlesen könnte (zumindest ist das bei uns so). Und ehrlich gesagt habe ich auch keine Lust, jedesmal, wenn ich eine mir bekannte Methode aufrufe, vorher zu überprüfen (Doc oder Quellcode), ob nicht evtl. ein Kollege etwas an der Methode verändert hat, so dass eine RuntimeException auftreten kann.

Im Großen und Ganzen schließe ich mich aber der Meinung von musiKk an.
 
M

maki

Gast
Deshalb finde ich auch an solchen Stellen RuntimeExceptions nicht so sinnvoll. Ich weiß lieber was geworfen werden kann, als zu raten oder stundenlang API-Doc zu lesen. Dann ruft ne Methode, die RuntimeExceptions wirft ne andere Methode auf, die andere RuntimeExceptions wirft, welche wiederrum eine aufruft, die nochmals andere RuntimeExceptions wirft. Und irgendwo hat nur einer einmal vergessen ne RuntimeException in die Doku zu schreiben bzw. aus der Doku von ner aufrufenden Methode zu übernehmen. Schon ham wir den Salat.
Naja, kann dem Argument nicht ganz folgen, vor allem wenn man sich die Vor- und Nachteile der checked Exceptions vs. unchecked ansieht, ist das, wenn man es denn als Problem sieht, steht das in keinem Verhältnis zu den Nachteilen der checked Exceptions.

Ganz davon abgesehen, dass bei interner Entwicklung eher weniger (und vor allem nicht während der Entwicklung eines größeren Projekts) eine API-Doc generiert wird,
Da habe ich andere Erfahrungen, Maven Projekte haben eigentlich immer die JavaDoc dabei ;)
Wobei natürlich die JAvaDoc geschrieben sein muss, wie gesagt, die Exceptions dokumentieren ist imho einer der wichtigsten Punkte.
 
Zuletzt bearbeitet von einem Moderator:
B

bygones

Gast
Ganz davon abgesehen, dass bei interner Entwicklung eher weniger (und vor allem nicht während der Entwicklung eines größeren Projekts) eine API-Doc generiert wird
ihre Entwickelt API ohne doku ? autsch... interne Entwicklung hin oder her - APIs gehoeren dokumentiert... alles andere ist unverantwortlich imho
 

The_S

Top Contributor
Naja, kann dem Argument nicht ganz folgen, vor allem wenn man sich die Vor- und Nachteile der checked Exceptions vs. unchecked ansieht, ist das, wenn man es denn als Problem sieht, steht das in keinem Verhältnis zu den Nachteilen der checked Exceptions.

Ich sag ja nicht, dass checked Exceptions immer geeigneter als unchecked Exceptions sind. Es kommt immer auf den Kontext und die Verwendung an. Bei uns gabs halt jetzt einige Situationen, wo ich über unchecked Exceptions "nicht so erfreut" war.

ihre Entwickelt API ohne doku ? autsch... interne Entwicklung hin oder her - APIs gehoeren dokumentiert... alles andere ist unverantwortlich imho

Das habe ich nicht gesagt. Ist schon alles dokumentiert. Wir generieren nur nicht nach jedem Änderungen eine neue Doku aus dem dokumentierten Quellcode. Ich meinte, wenn ich eine Methode auswendig kenne, habe ich keine Lust, bei jedem Aufruf in die Doku zu gucken, ob ein anderer Entwickler evtl. etwas daran geändert hat, und jetzt eine zusätzliche RuntimeException geworfen werden könnte. Noch schlimmer ist es, wenn Methoden bereits verwendet werden und dann nachträglich abgeändert werden müssen. Ich müsste dann jede aufrufende Methode mehr oder weniger händisch überprüfen, ob denn die evtl. neu geworfene RuntimeException korrekt behandelt wird. Hätte ich keine RuntimeException, würde ich sofort in meiner IDE sehen, wo ich jetzt eine Fehlerbehandlung nachziehen muss.

Klar, wenn man Zeit hat, kann man auch RuntimeExceptions verwenden und dann alle aufrufenden Methoden und deren aufrufenden Methoden und deren aufrufenden Methoden, ... raussuchen und anpassen. Die Zeit fehlt mir aber meistens (bzw. ich könnte sie an einer anderen Stelle besser gebrauchen).

Mit eurer Kritik stimme ich aber voll und ganz überein. Es gibt definitiv Situationen, wo RuntimeExceptions die deutlich bessere wahl sind. Dennoch habe ich lieber ein robustes Programm, wo eventuelle Fehler möglichst sinnvoll abgefangen werden, und nicht die Gefahr besteht, Exceptions einfach zu übersehen.
 

tfa

Top Contributor
Ich sag ja nicht, dass checked Exceptions immer geeigneter als unchecked Exceptions sind. Es kommt immer auf den Kontext und die Verwendung an. Bei uns gabs halt jetzt einige Situationen, wo ich über unchecked Exceptions "nicht so erfreut" war.

Ich nehme mal an, diese Situationen hätten sich durch vollständige Dokumentation und ausreichendes Testen vermeiden lassen (zwei Sachen, die man sowieso tun sollte, Exceptions hin oder her). Mit der gleichen Begründung könntest du RuntimeExceptions ganz abschaffen und alles checked machen.
 

The_S

Top Contributor
Ich nehme mal an, diese Situationen hätten sich durch vollständige Dokumentation und ausreichendes Testen vermeiden lassen (zwei Sachen, die man sowieso tun sollte, Exceptions hin oder her).

Ist bei uns gegeben. Ich bin nur zu Faul bei jedem Methodenaufruf nachzugucken, was denn wann und warum geworfen werden könnte ;) . Da ich durch RuntimeExceptions jedoch dazu gezwungen bin, bin ich in dieser Situation damit nicht 100pro zufrieden.
 

Sergeant_Pepper

Bekanntes Mitglied
Hallo,
ich habe das Thema mit Interesse verfolgt, die Unterscheidung "checked" <--> "unchecked" war mir bisher nicht bewusst bzw. bekannt.
Kann man zusammengefasst einfach sagen: wenn mich der Compiler (bzw. Eclipse) anmeckert, ich soll eine Exception entweder fangen oder "throws" zur Methode hinzufügen, dann ist es eine "checked exception" ?
 
B

bygones

Gast
Ist bei uns gegeben. Ich bin nur zu Faul bei jedem Methodenaufruf nachzugucken, was denn wann und warum geworfen werden könnte ;) . Da ich durch RuntimeExceptions jedoch dazu gezwungen bin, bin ich in dieser Situation damit nicht 100pro zufrieden.
d.h. du nutzt also fremde (wenn auch hausinterne) API ohne zu schauen / wissen was sie tut ?
ich gehe mal von (aus meiner sicht) normalfall aus, dass man eine Funktionalitaet nutzen will die es als API schon gibt, ergo schaue ich in der Doku / source nach ob es genau das tut was es proklamiert .... somit bekommt man auch die information bzgl sideeffects bzw exceptions.

bygones

das wird eher nun zu einer allgemeinen "doku - design - Api" diskussion und entfernt sich n bisschen dem eigentlichen Thema ;-)
 

tfa

Top Contributor
Hallo,
ich habe das Thema mit Interesse verfolgt, die Unterscheidung "checked" <--> "unchecked" war mir bisher nicht bewusst bzw. bekannt.
Kann man zusammengefasst einfach sagen: wenn mich der Compiler (bzw. Eclipse) anmeckert, ich soll eine Exception entweder fangen oder "throws" zur Methode hinzufügen, dann ist es eine "checked exception" ?
Ja, das ist eine Auswirkung von checked Exceptions. Allgemein kann man sagen, dass unchecked Exceptions von der Klasse RuntimeException (oder deren Unterklassen) abgeleitet sind. Checked Exceptions dagegen nicht.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
U Methoden Code Quality und Stil Java Basics - Anfänger-Themen 5
kaoZ Stil ? - ....Nein nicht das Ende des Besens ^^ Java Basics - Anfänger-Themen 11
M Vererbung Schlechter Stil? Java Basics - Anfänger-Themen 10
B Grundsätzliche Klassen-Struktur/Stil Java Basics - Anfänger-Themen 12
S Mein Code is unübersichtlich - besseren Stil Java Basics - Anfänger-Themen 6
S Unbeschaeftigten Thread in einer Schleife schlafen legen? Schlechter Stil? Java Basics - Anfänger-Themen 7
S Schlechter Stil beim Exception Handling Java Basics - Anfänger-Themen 6
J Getter und Setter auch intern benutzen - guter Stil? Java Basics - Anfänger-Themen 31
nabla Code Stil -- Eclipse Warnings Java Basics - Anfänger-Themen 9
P DotComVersenken -Spiel im Schiffeversenken-Stil - erstellen- Komm jetzt nicht weiter. Java Basics - Anfänger-Themen 11
P Spiel im Schiffe-Versenken Stil, Problem mit Erstellung des zweidimensionalen ARRAYs Java Basics - Anfänger-Themen 7
S sauberer Stil von return Wert (try, catch, finally) Java Basics - Anfänger-Themen 9
hdi Programmier-Stil : Speicher vs. Quellcode Java Basics - Anfänger-Themen 67
U Vernünftige Strukturierung, Guter Stil,. Java Basics - Anfänger-Themen 12
K BufferedReader im Konstruktor // guter Stil ? Java Basics - Anfänger-Themen 2
F Zugriff auf Instanzvariablen, Frage zum guten Stil Java Basics - Anfänger-Themen 2
J Guter Stil der Java-Programmierung Java Basics - Anfänger-Themen 5
G Array mit Schleife durchlaufen - guter Stil? Java Basics - Anfänger-Themen 20
frau-u guter Stil - wie macht mans am Besten? Java Basics - Anfänger-Themen 8
H schlechter objektorientierter stil Java Basics - Anfänger-Themen 6
M Test auf Exceptions schreiben Java Basics - Anfänger-Themen 11
berserkerdq2 Habe zwei exceptions, welche ist ein Kommunikationsfehler und welche ein Ausgabefehler? Java Basics - Anfänger-Themen 4
julian112 Input/Output .gz bzw. .txt Datei Einlesen und Umgang mit Exceptions Java Basics - Anfänger-Themen 1
C Exceptions identifizieren Java Basics - Anfänger-Themen 5
A Exceptions mit objektreferenzen Java Basics - Anfänger-Themen 4
A Exceptions und methods Java Basics - Anfänger-Themen 2
A Cannot find symbol bei exceptions Java Basics - Anfänger-Themen 2
A Exceptions und Packages Java Basics - Anfänger-Themen 6
B JUnit / Exceptions/ try-catch Java Basics - Anfänger-Themen 6
X Exceptions Benutzereingaben Java Basics - Anfänger-Themen 4
F Exceptions in Interfaces Java Basics - Anfänger-Themen 4
F Mehrere Exceptions in einem Catch-Block abfangen Java Basics - Anfänger-Themen 12
L Exceptions und Konten Java Basics - Anfänger-Themen 21
D Frage zu Exceptions Java Basics - Anfänger-Themen 8
I Wie programmiert man Exceptions? Java Basics - Anfänger-Themen 4
N Unterschied zwischen Checked und Unchecked Exceptions Java Basics - Anfänger-Themen 12
C Erste Schritte Exceptions nicht verstanden Java Basics - Anfänger-Themen 2
J Fragen zu Exceptions Java Basics - Anfänger-Themen 24
T Exceptions - ausgeführte Zeilen Java Basics - Anfänger-Themen 4
J Exceptions Java Basics - Anfänger-Themen 69
C Exceptions Java Basics - Anfänger-Themen 8
C Exceptions Java Basics - Anfänger-Themen 6
A ArrayQueue mit Exceptions und Vererbung Java Basics - Anfänger-Themen 3
F Exceptions Java Basics - Anfänger-Themen 6
J Frage zum Thema Exceptions (Try/Catch) Java Basics - Anfänger-Themen 3
M "Exceptions abfragen" Java Basics - Anfänger-Themen 6
Farbenfroh Exceptions Anfänger - Finde Fehler nicht Java Basics - Anfänger-Themen 7
Z Catch & Exceptions Java Basics - Anfänger-Themen 4
N Compiler-Fehler Drei Exceptions in GUIHack für Dreiecke auf MoveButtons Java Basics - Anfänger-Themen 36
V Welche Exceptions müssen importiert werden? Java Basics - Anfänger-Themen 3
S Exceptions Java Basics - Anfänger-Themen 7
M Vererbung Problem Vererbung/Exceptions Java Basics - Anfänger-Themen 9
S Verschachtelte Exceptions - Übersicht verbessern Java Basics - Anfänger-Themen 2
J Eclipse Exceptions Java Basics - Anfänger-Themen 2
K Schleifen und Exceptions Java Basics - Anfänger-Themen 8
K Exceptions auslagern Java Basics - Anfänger-Themen 15
R NullPointer Exceptions Java Basics - Anfänger-Themen 3
F Erste Schritte Übung zu Exceptions Java Basics - Anfänger-Themen 24
R Exceptions (try/catch) Java Basics - Anfänger-Themen 63
H Int Exceptions Java Basics - Anfänger-Themen 12
M Exceptions per throws oder try Java Basics - Anfänger-Themen 4
M Compiler-Fehler Queue als ArrayList mit Exceptions Java Basics - Anfänger-Themen 3
T Exceptions in einer Klasse Java Basics - Anfänger-Themen 3
B Eigene Exceptions entwerfen Java Basics - Anfänger-Themen 3
H Methoden Überflüssige Exceptions Java Basics - Anfänger-Themen 20
C Exceptions Java Basics - Anfänger-Themen 14
1 While Schleife Exceptions Java Basics - Anfänger-Themen 6
I Erste Schritte Eigene Fehlermeldungen bei Exceptions Java Basics - Anfänger-Themen 19
D Frage zu Exceptions Java Basics - Anfänger-Themen 12
M Compiler-Fehler Exceptions lieber throwen oder direkt catchen? Java Basics - Anfänger-Themen 8
T Exceptions Java Basics - Anfänger-Themen 19
B Wie finde ich Exceptions? Java Basics - Anfänger-Themen 19
Dit_ Input/Output Alle Exceptions protokollieren Java Basics - Anfänger-Themen 9
T Exceptions Java Basics - Anfänger-Themen 12
J Standard Exceptions abfangen Java Basics - Anfänger-Themen 5
F Exceptions werfen oder catchen?? Java Basics - Anfänger-Themen 14
D Exceptions - Ausnahmebehandlung Java Basics - Anfänger-Themen 19
D Frage zu Exceptions und der import Anweisung Java Basics - Anfänger-Themen 12
J Paar Fragen zu Exceptions Java Basics - Anfänger-Themen 16
G Verständnisproblem: Exceptions Java Basics - Anfänger-Themen 17
S Exceptions bei push/pop in Stack Java Basics - Anfänger-Themen 8
C Exceptions beim Beenden Java Basics - Anfänger-Themen 2
C TimerTask und Exceptions Java Basics - Anfänger-Themen 5
E Klasse öffnen, mehrere Exceptions Java Basics - Anfänger-Themen 9
C Exceptions Java Basics - Anfänger-Themen 7
G 2 Exceptions in einer Methode Java Basics - Anfänger-Themen 3
firefexx Exceptions werfen Java Basics - Anfänger-Themen 5
0 Exceptions mehrfach fangbar? Java Basics - Anfänger-Themen 4
O Exceptions Java Basics - Anfänger-Themen 3
K Sinn eigener Exceptions Java Basics - Anfänger-Themen 11
H Diverse Exceptions - Troubleshooting Java Basics - Anfänger-Themen 3
J exceptions Java Basics - Anfänger-Themen 8
sc0p InterruptedExceptions und Exceptions - in Einem! Java Basics - Anfänger-Themen 5
M Frage zu Exceptions Java Basics - Anfänger-Themen 19
M Fragen zu Exceptions Java Basics - Anfänger-Themen 3
A Exception Verständnisfrage: Exceptions während, einer Statischenzuweisung abfangen Java Basics - Anfänger-Themen 10
D Exceptions werfen + beenden Java Basics - Anfänger-Themen 12
M Exceptions aus interface-Methoden Java Basics - Anfänger-Themen 2
S File.renameTo und Exceptions / Fehlermeldung Java Basics - Anfänger-Themen 2
B Exceptions in Liste sammeln? Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben