# Exception weiterleiten



## downandout (1. Jun 2011)

Hallo,

ich habe eine Klasse, die ist dafür zuständig aus einem Textfile einzulesen:

Dabei wirft sie einige Exceptions, die ich aber in die andere Klasse umleiten will!
Wie mache ich das?

Vielen dank für jede Hilfe!


```
package aufgabe;

import java.io.*;

public class ReadFile{
	private BufferedReader in;
	
	public ReadFile(String path, String name) {
		try {
			in = new BufferedReader(new FileReader(new File(path, name)));
			boolean fehler = false;
			}
		catch (IOException e) {
			System.out.println("Fehler beim Öffnen: " + e);
			}
		}
	
	public String readLine() {
		String s = null;
		try {
			s = in.readLine();
			}
		catch (IOException e) {
			System.out.println("Fehler beim Lesen: " + e);
			}
		return s;
		}
	
	public void close() {
		try {
			in.close();
			}
		catch (IOException e) {
			System.out.println("Fehler beim Schließen: " + e);
			}
		}


	public static void main(String args[]) {}
	}
```

Programm das ReadFile verwendet:


```
public class BuchstabenZeichnen extends Applet
{.......

public BuchstabenZeichnen(){

	String path = "C:/Users/Marko/workspace/aufgabe4/testdaten";
	ReadFile file = new ReadFile(path, "banner.txt");
	
	String s;
	
	while (null != (s = file.readLine()))
		string_array.add(s);
	file.close();

}
```


----------



## Final_Striker (1. Jun 2011)

downandout hat gesagt.:


> Dabei wirft sie einige Exceptions, die ich aber in die andere Klasse umleiten will!
> Wie mache ich das?




```
public void close() throws IOException {
 ...
}
```


----------



## Spacerat (1. Jun 2011)

Äehm... @downandout: Zumindest scheinst du im richtigem Forum zu sein.
Bei Exceptions gibt es die sog. *catch or throw* Regel, die besagt, das Ausnahmen (Exceptions) behandelt (catch) oder in der Hierarchie nach oben hin weitergereicht (throw) werden müssen. Okay... nicht bei allen Exceptions ist des so z.B. NullPointer, IllegalArgument, Runtime usw. der Name für diese Ausnahme Exceptions :lol: ist mir leider grad' entfallen.
Also: In einer Methode soll eine Datei gelesen werden. Beim Lesen dieser Datei kann immer wieder eine IOException auftreten. Diese musst du nun behandeln, so wie du es in deinem Beispiel getan hast oder halt weiterreichen. Zum Weiterreichen genügt es, wenn man die entsprechenden Exceptions, die geworfen werden sollen, als *throws* clause mit an die Methodendefinition anhängt. Das ganze würde für dein Beispiel dann so aussehen:
	
	
	
	





```
package aufgabe;
 
import java.io.*;
 
public class ReadFile{
    private BufferedReader in;
    
    public ReadFile(String path, String name) throws IOException {
            in = new BufferedReader(new FileReader(new File(path, name)));
        }
    
    public String readLine() throws IOException {
        return in.readLine();
        }
    
    public void close() throws IOException {
            in.close();
        }
 
 
    public static void main(String args[]) {}
    }
```

@Edit: ...und ich hab' jetzt nicht wirklich knapp 'ne halbe Stunde für die Erklärung gebraucht, odä? :shock:


----------



## hdi (1. Jun 2011)

Um das zu vervollständigen, was Spacerat angesprochen hat: 

Exceptions werden in 2 Klassen eingeteilt: _Checked _Exceptions und _Unchecked _Exceptions

Unchecked Exceptions sind Instanzen der Klasse _RuntimeException _sowie alle davon ableitenden Klassen. Solche Exceptions müssen nicht behandelt werden. D.h. man braucht weder ein try-catch noch ein throws. Wenn man sie behandelt (was natürlich durchaus geht), und man entschließt sich dazu sie weiterzuwerfen, dann ist es nicht nötig das in der Methoden-Signatur bekanntzumachen. (Und man sollte das auch nicht tun!)

Checked Exceptions sind alle anderen Exceptions, also eben jene die nicht von RuntimeException ableiten. zB IOException (du kannst ja in der API nachkucken, wie die Vererbungshierarchie aussieht). Diese _musst _du entweder mit try-catch abfangen oder per throw weiterwerfen. Und bei denen musst du beim Weiterwerfen dann auch die Methoden-Signatur entsprechend anpassen.


----------



## tfa (1. Jun 2011)

Wenn man mit Checked Exceptions zu kämpfen hat, ist es  gängige Praxis, diese in RuntimeExceptions zu kapseln und einfach weiter zu werfen (wenn man sie nicht an Ort und Stelle behandeln kann, was meistens der Fall ist):

```
public ReadFile(String path, String name) {
        try {
            in = new BufferedReader(new FileReader(new File(path, name)));
            boolean fehler = false;
            }
        catch (IOException e) {
            throw new RuntimeException(e);
            }
        }
```
Das ist sicher besser, als überall "throws ..." dranzuschreiben.


----------



## hdi (1. Jun 2011)

@tfa

Woher hast du denn _das_? Eine IOException ist beim Zugriff auf das Dateisystem nie auszuschließen. Datei grad von einem anderen Programm geöffnet, OS gibt kein Schreibrecht etc. Seit wann ist es "gängige Praxis" das Programm in solchen Fällen einfach abstürzen zu lassen? Dadurch, dass du die throws-Deklaration einer Checked Exceptions weglässt ist sich der Aufrufer gar nicht mehr darüber bewusst, dass sowas passieren kann.



> Das ist sicher besser, als überall "throws ..." dranzuschreiben.


So wie es besser ist das Programm mit fehlerhaften Daten arbeiten zu lassen, als überall "if x != null" dranzuschreiben? Das ist doch Quatsch, lol du bist zu faul für eine throws-Deklaration und nimmst dafür Abstürze in Kauf?

Also.. "gängige Praxis" ist soweit ich weiß folgendes:
- Wenn es sich beim Auftreten der Exception um einen Bug (Programmierfehler) handelt: Unchecked Exception. Denn reagieren sollte man darauf sowieso nicht, wenn sie Auftritt muss man irgendwas im Design verändern. (D.h. solche Exceptions sollten im fertigen Produkt nie auftreten)

- Wenn es sich um einen *erwartbaren*, *unvermeidbaren *Fehler zur Laufzeit handelt: Checked Exception! Eben weil du den Aufrufer damit darauf aufmerksam machst und er darauf reagieren soll. Und sei es auch nur mit einer entsprechenden Fehlermeldung und anschließender Programm-Terminierung. Aber einfach so durchrasseln lassen und das Programm abstürzen lassen, das ist ja wohl nicht die feine Art


----------



## SlaterB (1. Jun 2011)

was ist denn das für eine Ausdrucksweise? bei nur 5 statt 2670 Postings könnte man da über Verwarnung nachdenken..

wie große Programme mit zig verschachtelten Ebenen, hunderten Verzweigungen, Interfacen usw. aussehen kann man sich pauschal nicht unbedingt vorstellen,
da kann es sehr sehr viel Arbeit machen x00 mal throws ranzuschreiben und hat dann auch noch ein schlechteres Programm als vorher, der nächste muss das alles wieder entfernen..

eine Fehlerbehandlung gibt es in kontrollierten Programmen an zentralen Stellen sowieso, 
ob da nun eine IOException oder eine RuntimeException ankommt, wo liegt der Unterschied? das Programm 'stürzt' in jedem Fall 'ab',
(eine RuntimeException ist kein Programmende, falls du das denkst)

es ist allein eine Information auf den Zwischenebenen, ob hier eine IOException vorbeikommen kann oder nicht, 
du hälst das vielleicht für einen Vorteil, aber es kann gerade auch besser sein wenn das nicht überall steht,
Programme teilen sich in Module auf, die untereinander unabhängig sein sollen, austauschbar sind,
die Logik-Schicht arbeitet mal mit einem Web-Frontend oder mal mit einer Swing-GUI, hinten dran steht eine Hibernate-Datenbank oder ein Dateisystem oder ein WebService,
sollen für alle Situationen alle möglichen Exceptions aufgezählt werden?

es spricht nichts dagegen, throws IOException zu benutzen wenn man es für sinnvoll hält,
mindesten in ein paar zusammenhängenden Klassen kann es sogar auch ein tfa gut finden 
aber genauso ist die Vorstellung erlaubt, an bestimmten Programmpunkten auf allgemeine Fehlerarten zu wechseln


----------



## ARadauer (1. Jun 2011)

Man kann seine Schnittstellen, die ja eher abstrakter sein sollen, sauber von Details der Implementierung (SQLException) sauber halten... das ist für mich ein großer Vorteil von Unchecked Exceptions


----------



## mvitz (1. Jun 2011)

hdi hat gesagt.:


> ...
> Unchecked Exceptions sind Instanzen der Klasse _RuntimeException _sowie alle davon ableitenden Klassen. Solche Exceptions müssen nicht behandelt werden. D.h. man braucht weder ein try-catch noch ein throws. Wenn man sie behandelt (was natürlich durchaus geht), und man entschließt sich dazu sie weiterzuwerfen, dann ist es nicht nötig das in der Methoden-Signatur bekanntzumachen. (Und man sollte das auch nicht tun!)
> ...



Da stimme ich nicht 100% überein. Gerade wenn man sich entschließt generell keine Checked und nur RuntimeExceptions zu werfen, dann sollte man auch dokumentieren, welche RuntimeExceptions eine Methode werfen kann. (Spring z.B. benutzt fast ausschließlich RuntimeExceptions und added diese [zumindest teilweise] an die Methoden, siehe z.B. JdbcOperations DataAccessException erbt von RuntimeException)


----------



## tfa (1. Jun 2011)

@hdi:

Deine Auffassung vom Exceptions-Konzept in Java ist etwas veraltet. So hat man das früher mal gedacht. Die Sache mit den Checked/Unchecked Exceptions hat sich aber eher als problematisch herausgestellt. Die anderen haben ja schon ein paar Gründe genannt. Weiteres findest du hier im FAQ-Beitrag "Was ist eine Exception?".



> es spricht nichts dagegen, throws IOException zu benutzen wenn man es für sinnvoll hält,
> mindesten in ein paar zusammenhängenden Klassen kann es sogar auch ein tfa gut finden


Möglich. Ich schreibe an private Methoden normalerweise die throws-Klausel für checked Exceptions. In den aufrufenden öffentlichen Methoden kommt dann das try-catch mit Behandlung (eher selten) oder weiterwerfen der RuntimeException.


----------



## maki (1. Jun 2011)

Checked Exceptions sind ein misslungenes Experiment, welches seit dem auch nicht mehr wiederholt wurde(keine andere Sprache hat diesen Fehler nachgemacht, auch hat keine komplett neue JDK API mehr checked Exceptions verwendet), die Nachteile sind einfach zu gravierend, wenn man sie mit eventuellen Vorteilen vergleicht.


----------



## downandout (1. Jun 2011)

Vielen Dank für die umfangreiche Diskussion!

Ich habe überall das throw angehängt. Hat dazu geführt, das ich in der Klasse mit der ich Readfile auslese die Exceptions bekommen habe.

Das habe ich mit throw gelöst, aber was mir nicht passt vorher könnte ich genaue Fehlermeldungen selber schreiben wo was nicht passt, kann ich das jetzt nicht auch noch machen?

Damit meine ich: zB der Pfad ist fehlerhaft und ich bekomme: "Fehler beim Öffnen: "

Danke für eure Hilfe!


```
package aufgabe;

import java.io.*;

public class ReadFile{
	private BufferedReader in;
	
	public ReadFile(String path, String name)  throws IOException {
			in = new BufferedReader(new FileReader(new File(path, name)));
			boolean fehler = false;
		}
	
	public String readLine()  throws IOException {
		String s = null;
			s = in.readLine();
		return s;
		}
	
	public void close() throws IOException  {
			in.close();
		}

	/* Testprogramm */
	public static void main(String args[]) throws IOException {
		String path = "./testdaten";
		ReadFile file = new ReadFile(path, "banner.txt");

		String s;
		while (null != (s = file.readLine()))
			System.out.println(s);

		file.close();
		}
	}
```

Das hat in der aufrufenden Klasse dazu geführt das ich auch ein throw benötige:


```
public BuchstabenZeichnen()throws IOException {

	String path = "C:/Users/Marko/workspace/aufgabe4/testdaten";
	ReadFile file;
	
	file = new ReadFile(path, "banner.txt");

	
	String s;
	
	while (null != (s = file.readLine()))
		string_array.add(s);
	file.close();


}
```


----------



## hdi (1. Jun 2011)

> was ist denn das für eine Ausdrucksweise? bei nur 5 statt 2670 Postings könnte man da über Verwarnung nachdenken..


Hoppla - das sollte überhaupt nicht angreifend rüberkommen?! Sorry dafür, war überhaupt nicht so beabsichtigt/empfunden, ich war nur sehr verwundert. (Manchmal vergisst man halt vor einen Satz das "Ich finde" oder "imho" und dann kommt das vllt etwas anders rüber)



> Gerade wenn man sich entschließt generell keine Checked und nur RuntimeExceptions zu werfen, dann sollte man auch dokumentieren, welche RuntimeExceptions eine Methode werfen kann.


Ja das finde ich auch, aber ich rede von der throws-Deklaration - gegen ein _@throws_ in der JavaDoc habe ich keinesfalls etwas. Das findet man ja an diversen Stellen in der API-Doc, allerdings gibt es soweit ich weiß keine (oder fast keine) Methoden, die eine Unchecked Exception wirklich _deklarieren_.



> ob da nun eine IOException oder eine RuntimeException ankommt, wo liegt der Unterschied? das Programm 'stürzt' in jedem Fall 'ab',
> (eine RuntimeException ist kein Programmende, falls du das denkst)


Naja der Unterschied liegt halt darin, dass das Auftreten von Unchecked Exception (für den Compiler) geheim gehalten wird, was halt etwas gefährlich ist wie ich finde - das kann man dann beim Aufruf der Methode schnell vergessen. Und _dann _stürzt das Programm (ok: Thread) ab, weil man die nirgendswo abfängt. Bei Fehlern die eh nicht auftreten sollten ist das ja ok (zB IllegalArgumentException -> Das ist ein Problem des Aufrufers, also ein Bug den man lösen kann). Aber bei unvermeidlichen Dingen wie einer IOException... Wieso sollte die Methode so tun als könnte nix passieren, obwohl es nicht so ist? Nur, damit ein eventuelles Refactoring später angenehmer ist? ...Mag sein, ich gestehe ich hab bisher keine so komplizierte App geschrieben dass ich da hunderte Ebenen hätte. Aber ich seh grad außer Bequemlichkeit keinen Grund für den Verzicht auf Checked Exceptions, ich finde die machen die Benutzung der betroffenen Methoden *******-sicher. Und das ist ja schon immer ein Ziel im Design oder? Ich meine warum überhaupt private Instanz-Variablen? Ich kann immer sicherstellen dass ich alles richtig mach. Aber ich fühl mich besser wenn das der Compiler für mich garantiert.


----------



## maki (1. Jun 2011)

hdi, checked Exceptions haben ein paar Konstruktionsfehler, zB. wird der Entwickler gezwungen, entweder ein try/catch block oder eine throws Klausel einzufügen, selbst wenn gar nicht vernünftig auf die Execption reagiert werden kann, oder die Exception gar nicht auftreten kann, aber von der Singatur auferzwungen wurde.

Beispiele für Exceptions die nicht auftreten können:

```
try {
            address = InetAddress.getLocalHost().getHostAdress();
        } catch (final UnknownHostException ignore) {
            // leerer catch block weil die Exception niemals aufteten kann
        }
```

Beispiel für eine Exception die nichtmal theoretisch auftreten kann, deren "Behandlung" aber von der Signatur (throws) auferzwungen wird:

```
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {   
	out.write(bytes);   
	out.close()   
	return out.toSring(); 
} catch (IOException e) {   
// unmöglich hierhin zu kommen
	}
```
Wie du siehst, sind checked Exceptions zwar auf dem Papier gut, in der Realität aber nicht.
Die theorie war, das man  so schon den Entwickler zwingen kann, sinnvoll mit der Exception umzugehen, aber in der Realität kann man den Entwickler nicht dazu zwingen, sinnvollen Code zu schreiben, zumindest nicht mit checked Exceptions.

Dazu kommt, dass es u.U. keine gute Möglcihekit gibt, die Exception an dieser Stelle zu behandeln, also muss man throws an die Methode dranhängen, zum Schluss weiss sogar die GUI dass irgendwo IOExceptions oder gar SQLException gweorfen werden köönnen -> sog. "leaky abstraction", Kapselung wird gebrochen.
Da kann man dann doch nur wieder RuntimeExceptions nutzen, durch Exception Translation, wie tfa zeigte.

Alles in allem sind checked Exceptions eben keine gute Sache...


----------



## hdi (1. Jun 2011)

> checked Exceptions haben ein paar Konstruktionsfehler, zB. wird der Entwickler gezwungen, entweder ein try/catch block oder eine throws Klausel einzufügen, selbst wenn gar nicht vernünftig auf die Execption reagiert werden kann, oder die Exception gar nicht auftreten kann


Das sind dann aber Entscheidungsfehler beim Design der einzelnen Exceptions. Ja, ich find auch manche Exceptions hätten die Leute von Sun ruhig Unchecked machen können. Aber das Modell an sich macht trotzdem Sinn: Wenn irgendwo ein *nicht vermeidbarer* Fehler auftreten kann, dann sollte man gezwungen sein den irgendwo zu behandeln. Denn sonst hat man die Möglichkeit das Programm abstürzen zu lassen, und es gibt ja wohl keinen Fall wo man sich wirklich dafür entscheiden möchte. Also: Wenn wir uns einig sind dass Exception X irgendwo abgefangen werden soll - wieso das nicht vom Compiler sicherstellen lassen? Deswegen sag ich ja ich seh nur Bequemlichkeit dahinter, es ist ja nicht so dass der Compiler einen zu etwas zwingt was man nicht will. Man will sie ja abfangen. Ja Refactoring geht super wenn man die Methoden-Signatur nicht veränder muss, aber genauso super geht es dabei ein try-catch rauszulöschen und an keiner anderen Stelle einzubauen. Und dann hat man halt nen Fehler mit Programmabsturz.


----------



## maki (1. Jun 2011)

> Das sind dann aber Entscheidungsfehler beim Design der einzelnen Exceptions.


Nö, das ist ein Designfehler von chekced Exceptions an sich.
Das ist nämlich genau der Denkfehler der zu checked Exceptions geführt hat, man kann nicht wissen ob eine bestimmte Exception sich behandlen lässt oder nicht.

Man kann niemals im voraus wissen, ob eine Exception sinnvoll behandelt werden kann oder nicht, das gilt für die IOExceptions  als auch für jede (!) andere checked Exception.

Beispiel: java.io.File operationen, IOException fliegt, und was macht dein Programm wenn die Platte voll ist? -> Nix, Fehlermeldung, beenden, fertig, das geht genausogut mit unchecked/RuntimeExceptions.

Heute sollte man schlauer sein 



> . Also: Wenn wir uns einig sind dass Exception X irgendwo abgefangen werden soll - wieso das nicht vom Compiler sicherstellen lassen?


Sind wir nicht, du begehst nämlich denselben Fehler wie die Sun Jungs damals, man kann nix erzwingen, der Compiler schon gar nicht.

Ist aber alles Schnee von gestern, wurde schon 1000013 mal Diskutiert, mit dem gleichen Ergebniss: checked Exceptions are evil


----------



## hdi (1. Jun 2011)

> Nix, Fehlermeldung, beenden, fertig


Naja Fehlermeldung und beenden ist finde ich halt nicht "Nix". Nix ist: Programm stürzt ohne jede Info ab, d.h. ohne dass man sich des Fehlers bewusst ist. Und das kann dir bei Unchecked Exceptions passieren, wenn du - gerade bei 100 Layern und etlichen Klassen und Methoden-Aufrufen - irgendwo ein try-catch vergisst. Bei Checked Exceptions geht das rein syntaktisch nicht, da müsstest du in der main/run-Methode die Exception per throws deklarieren, und sowas kann einem nicht aus Versehen passieren, das ist dann schon mutwillige Zerstörung des eigenen Programms 

Ich meine baut ihr dann um jede main und run Methode pauschal ein 
	
	
	
	





```
try{ rumpf } catch(Exception e)
```
 ? Sonst ist's doch echt möglich mal die Behandlung einer Exception zu vergessen. Und dann sind wenn's doof läuft wichtige Daten für immer verloren. Ich verstehe schon was ihr meint, ich find diese try-catch Blöcke auch nich sonderlich hübsch. Aber ich find's halt nur bisschen mutig sag ich mal ausschließlich Unchecked Exceptions zu verwenden. So nach dem Motto "ich weiß dass der Aufruf von x() intern zu 13 anderen Methoden-Aufrufen führt, von denen die letzte unter Umständen eine Exception werfen kann, also bau ich jetzt um diesen Aufruf ein try-catch damit das Programm nicht abstürzt". Ich würd damit glaub ich nicht klar kommen, wer soll denn da bei 500 Klassen und 6000 Methoden noch wissen wo jetzt was passieren kann, wenn's der Compiler euch nicht verrät? Teamarbeit an einem gemeinsamen Projekt kann ich mir so gar nicht vorstellen, das ist wie wenn mir einer nicht verrät was seine Methode mir zurückliefert. Das ist einfach ne wichtige Info die ich doch brauch als Aufrufer?


----------



## Crian (1. Jun 2011)

Was passiert denn deiner Meinung nach bei


```
public static void main(String[] args) {
        throw1();
    }

    private static void throw1() {
        throw new RuntimeException("Test1");
    }
```
?


----------



## hdi (1. Jun 2011)

Das Programm stürzt mit einer RuntimeException ab. Eventuelle Daten hab ich nicht gesichert. Ich hab einfach eine Methode aufgerufen ohne zu wissen dass sie zum Absturz führen kann, und hab halt mal gut Pech gehabt, oder etwa nicht?


----------



## maki (1. Jun 2011)

Wie gesagt, der Compiler kann nicht wissen ob & wo eine Fehlerbehandlung möglich ist, scheidet daher schon mal grundsätzlich aus. Was im kleinen/Theorie funzt kann in der Realität dann schon ein Problem werden.

Jedes große SW System hat irgendwo eine Stelle, an der alle(!) nicht gefangenen Exceptions auflaufen, bei Schichtsystemen muss man sogar zwischen jeder Schicht Exceptions "übersetzen", sonst hat das JSF Frontend gleich ganz schnell Abhängigkeiten zu JPA/Hibernate 
Vergessen kann man da nix, und falls doch, ist der Compiler auch keine Hilfe.

In der Realität ist es unmöglich, ohne unchecked (Runtime-) Exceptions zu arbeiten, es geht schlicht nicht, sonst wirft man die Kapselung über Bord.
Beispiel klassisches Schichtsystem: 
UI | Business | Integration

Die Integrationtier kann SqlExceptions werfen, wenn das nur per throws weitergegeben wird, muss die UI über SqlExceptions bescheid wissen, soll sie ja schliesslich fangen & darstellen.
Jetzt kennt das ganze System SQlExceptions und ist damit abhängig davon, man stelle sich vor wenn man JPA, JDO, XML etc. pp. als Persistenz verwendet wird... nix mit Schichtentrennung.
Man muss also RuntimeExceptions einsetzen, oft auch nur, um checked Exceptions weiterzuleiten


----------



## hdi (1. Jun 2011)

> der Compiler kann nicht wissen ob & wo eine Fehlerbehandlung möglich ist


Ne aber er kann (bei Checked Exceptions) wissen wo ein Programm-Absturz möglich ist. Ist ne nette Info wie ich finde.



> In der Realität ist es unmöglich, ohne unchecked (Runtime-) Exceptions zu arbeiten


Ich habe nie behauptet dass Unchecked Exceptions überflüssig sind. Ich behaupte nur dass Checked Exceptions _nicht _überflüssig sind.



> Jedes große SW System hat irgendwo eine Stelle, an der alle(!) nicht gefangenen Exceptions auflaufen


Also sieht jedes deiner Programme so aus:


```
public static void main(String[] args){ // bzw run() Methode eines Runnables
  try{
     doProgram();
  }
  catch(Exception e){
     CentralExceptionHandler.handle(e);
  }
}
```

?


----------



## maki (1. Jun 2011)

> Ich habe nie behauptet dass Unchecked Exceptions überflüssig sind. Ich behaupte nur dass Checked Exceptions nicht überflüssig sind.


Oh doch, sie sind überflüssig, das weiss ich daher, weil die immer zu unchecked Exceptions umgewandelt werden müssen, man will sich ja die Methodensignatur nicht versauen und Implementierungsdetails "entkommen" lassen.



> Also sieht jedes deiner Programme so aus:


Meine Programme haben eigentlich nie eine main Methode 

Aber im Prinzip gibt es mindestens eine Stelle, an der Exceptions gefangen werden, bevor die VM sich darum kümmern muss.
Wenn diese Stelle "vergessen" wird, dann hat das Team ganz andere Probleme als checked/unchecked Exceptions


----------



## hdi (1. Jun 2011)

Okay aber wenn es jetzt um eine normale SE App handelt mit main-Methode, dann würdest du das so machen oder? Wenn ja, dann hab ich damit kein Problem mehr. Ich weiß nur dass ich selbst mal danach gefragt habe, ob es nicht sinnvoll wäre das zu tun, damit man auch zu 100% keinen Programm-Absturz hat, von dem man nix weiß. Aber das kam iwie auch nicht so gut an. Aber so müsst ihr's ja wohl machen wenn ihr keine Checked Exceptions verwendet. Oder ihr seid euch verdammt sicher darin dass ihr niemals etwas überseht oder vergesst.


----------



## SlaterB (1. Jun 2011)

hdi hat gesagt.:


> Ne aber er kann (bei Checked Exceptions) wissen wo ein Programm-Absturz möglich ist. Ist ne nette Info wie ich finde.


wenn ein Programm erstmal so verzweigt ist, dass jede Exception quasi überall vorbeikommt,
dann hast du die Info überall stehen und letztlich keine Information gewonnen,

und dass Exceptions überall vorbeikommen ist ein wichtiger Punkt bei zentraler Fehlerbehandlung



> Also sieht jedes deiner Programme so aus:


die Alternative wäre ein Programm welches ich hier nicht poste, aber eben mit throws überall und letztlich doch auch irgendwo das try/catch

----

wenn eine Exception nicht zentral, sondern nahe am Auftreten behandelt wird, dann stellt sich die große programmweite Frage gar nicht,
und dafür sind CheckedExceptions durchaus brauchbar,
ich selber kann absolut damit leben, auch Richtung großer Programme, sie zwingt einen dann schön zur Kapselung,
Hibernate query.list() steht bei mir nach Möglichkeit nur einmal im Programm in einer Wrapper-Methode,
ob ich da noch 5 Zeilen dazuschreiben muss oder nicht.., die unchecked-HibernateException fange ich da genauso und wandle sie um,
wer dagegen query.list() übers ganze Datenbank-Programm verteilt sähe mit Checked Exceptions alt aus


----------



## hdi (1. Jun 2011)

Okay also bitte nochmal Klartext: Ich würdet es empfehlen jedes Programm mit einem einzigen großen try-catch in der main/run Methode aufzuziehen, um RuntimeExceptions verwenden und trotzdem auf der sicheren Seite sein zu können? Das würd ich ja verstehen. Aber nicht das Werfen von Unchecked Exceptions die nirgendwo gefangen werden (Wenn es sich um nicht vermeidbare Fehler wie I/O etc handelt).

Yes or no?


----------



## SlaterB (1. Jun 2011)

weder noch,

eine main-Methode braucht kein try/catch, wenn dort Exceptions ausgegeben werden und das Programm beendet wird oder die Exception den main-Thread beendet, kommt das gleiche raus,

interessanter sind periodische oder von User angestoßene Prozesse, z.B. ein WebServer wie dieses Forum, der einen Request eines Users erhält,
oder etwas einfacher gedacht in einer Java-GUI der ActionListener eines Buttons,
dort kommen Exceptions letzlich an ähnlich wie in einer main-Methode, gibt in der Konsole einen langen Stack-Trace 
und die Aktion ist beendet, die GUI läuft aber weiter,
die Konsole übersieht man oft, hier wäre eine Fehlerbehandlung zur Anzeige des Fehlers in einem Textfeld nötig,
generell ist das erstmal für alles gut, ob NullPointer, SQL- oder IO-Fehler oder Parsen der User-Eingabe,

es müssen nicht alle Fehler dort landen (User-Eingabe-Parser kann vielleicht die Fehler selber fangen und im Formular genauer kenntlich machen), aber sie können

---

> Aber nicht das Werfen von Unchecked Exceptions die nirgendwo gefangen werden
eine Exception ist nicht schlimmes, das Werfen derselben auch nicht, 
schlimmstenfalls kommt sie nirgendwo an und man hat (wenn man bei wichtigen Dingen bemerkt) eine viel wertvollere Info gewonnen, 
eine ganz wichtige Lücke im Programm gefunden, die auch die tausend möglichen normalen RuntimeExceptions bisher verschluckte,

in Fehlerfällen schaue ich nicht nur nach den Fehler an sich, sondern auch ob der Fehler gut dokumentiert wurde, wie ich darauf gestoßen bin, 
wo noch mehr Logausgaben dazugehören usw., 

im Extremfall wie bei Hibernate query.list() fange ich dort direkt den Fehler, gebe das SQL und den Aufrufer aus (was anderer Stelle nicht so leicht wäre) und werfe dann die Exception weiter,
später sehe ich dann evtl. zuerst die SQL-Ausgabe im Log und prüfe noch, wo die zugehörige Exception weiter gelandet ist, welche Prozesse daran hingen und ob und wie diese abgebrocken wurden

Daten verlieren usw. klingt abstrakt, bis man so wichtig agiert sollte alles zigfach getestet sein,
während man noch programmiert ist es eine andere Welt (ok, vielleicht nicht bei Test Driven Design  )


----------



## hdi (1. Jun 2011)

> eine Exception ist nicht schlimmes, das Werfen derselben auch nicht,


Ja ich weiß, deswegen bestand ja der zweite Teil des Satzes aus "die nirgendwo gefangen werden". Das ist nämlich etwas Schlimmes, denn das bedeutet Programm-Absturz. Und ein Absturz ist wie der Name schon sagt eben keine kontrollierte Terminierung, und in 0% der Fälle das was man will. (Ich rede jetzt nicht von Fehlern in der Programmier-Phase sondern Fehler beim fertigen Produkt)



> Daten verlieren usw. klingt abstrakt, bis man so wichtig agiert sollte alles zigfach getestet sein,


Da redest du jetzt aber über Programmierfehler, zB NullPointerException usw. Die müssen und sollen in der Tat nicht abgefangen werden, die sollen gar nicht erst auftreten. Aber es geht hier darum Unchecked Exceptions auch bei unvermeidbaren Fehlern zur Laufzeit zu verwenden, eben I/O usw. Und ich frag mich halt nur die ganze Zeit: Wieso traut ihr euch sowas? Wenn ihr kein try-catch um den GESAMTEN Code habt, knallen solche Fehler durch. Programm-Absturz, Datenverlust. Und zwar nicht nur in der Test-Phase, sondern im ausgelieferten Produkt, da es sich um einen nicht vermeidbaren Fehler handelt. Hmm :bahnhof:


----------



## SlaterB (1. Jun 2011)

wenn ich wegen einer umgewandelten IOException Angst hätte, dann auch wegen jeder NullPointerException usw.
Exceptions treten auf und wenn sie weiter oben nicht sinnvoll abgefangen werden, dann ist ein Programm oder eine Aktion zu Ende
oder schlimmer noch gar in einer Endlosschleife,
eine Webseite zeigt irgendwelche wirren Errors oder lädt ewig, eine GUI reagiert nicht mehr und ähnliches

das kann alles auftreten, wenn dann hat man wie im letzten Postings gesagt eine wichtige Lücke gefunden, aber wie vor 4 Zeilen gesagt: dafür gibts viele Ursachen

meine Strategie in diesen Fällen ist, umso mehr Dinge zusammenzufassen, möglichst viele Programmteile durch eine zentrale Kontrollklasse laufen zu lassen,
sobald ein Fehler auftritt wird nicht eine einzelne Fehlerquelle behandelt, sondern erstmal die Klasse/ der Prozess bzw. alle ähnlichen in den allgemeinen Ablauf eingebracht so dass in diesen auf (fast) alle Zeit garantiert nichts mehr passieren kann


----------



## F.S.WhiTeY (1. Jun 2011)

Leuts diskutiert doch bitte noch weiter und bleibt so sachlich  Ich lerne gerade soooo viel, ich hab im Studium bislang noch garnicht den Unterschied zwischen Unchecked Exceptions und Checked Exceptions erklärt bekommen. Exceptions an sich kenne ich wohl und auch den weg sie zu behandeln oder weiterzureichen aber das was ihr hier gerade diskutiert wurde bei uns außer acht gelassen. 


(Wen es interessiert: B.o.S. Angewandte Informatik an einer FH. Alle Grundlagenvorlesungen bestanden und auch verstanden. Zu grundlagen zähle ich: Designprinziepien, OOP, Grundlagen Prog. (Java), Algorithmen und Datenstrukturen.)


----------



## tfa (1. Jun 2011)

> Wenn ihr kein try-catch um den GESAMTEN Code habt, knallen solche Fehler durch. Programm-Absturz, Datenverlust. Und zwar nicht nur in der Test-Phase, sondern im ausgelieferten Produkt, da es sich um einen nicht vermeidbaren Fehler handelt.


Man muss natürlich schon sicherstellen, dass Exceptions nicht verloren gehen. Dazu wird es immer eine oder wenige zentrale Stellen der Exceptionbehandlung geben, wo die Ausnahmen auflaufen, die nicht explizit behandelt wurden. Dort kann man dem Anwender (sofern es eine Client-Anwendung ist) eine vernünftige Fehlermeldung präsentieren oder irgendwo die Alarmglocken klingeln lassen. 
In der Java-API gibt es sogar Mechanismen, die einen dabei unterstützen können: Thread.UncaughtExceptionHandler (Java Platform SE 6)


----------



## hdi (1. Jun 2011)

> wenn ich wegen einer umgewandelten IOException Angst hätte, dann auch wegen jeder NullPointerException usw.


Hm, da ist natürlich was dran... Wobei ich immer noch nen Unterschied sehe: NPEs sind Programmierfehler, die lassen sich vermeiden. Dann brauch ich natürlich auch kein catch mehr dafür. IOEs lassen sich nicht vermeiden, also kann ich nie sagen dass keine auftritt, und sollte demnach für den unglücklichen Fall ein catch haben, sonst halt Absturz.



> Man muss natürlich schon sicherstellen, dass Exceptions nicht verloren gehen.


Ja genau das meine ich ja: Bei Checked Exceptions übernimmt das der Compiler, bei Unchecked Exceptions muss man's halt selbst sicherstellen. Also wenn ich euch richtig verstehe gibt's halt echt so nen try{programm}catch(Exception e){...} Block in euren Programmen. Gut wenn man sich das angewöhnt gibt's natürlich keine Probleme.

...Naja ich lass euch jetzt erstmal wieder mal in Ruhe  Ich werd in nächster Zeit mal die Checked Exceptions zu RuntimeExceptions machen und kucken wie das dann so ist, vllt versteh ich's dann besser. Danke für eure Antworten!


----------



## downandout (1. Jun 2011)

Auf Seite 1 ist irgendwo bei eurer heftigen Diskussion meine Frage verloren gegangen...

Wäre cool wenn die noch wer beantworten würde... (ca. in der Mitte auf S1)


----------



## hdi (1. Jun 2011)

Du musst die Exception halt mit deiner eigenen Meldung anreichern bevor du sie weiterleitest:


```
public ReadFile(String path, String name)  throws IOException {
            try{
                   File file = new File(path, name);
                   in = new BufferedReader(new FileReader(file));
            }
            catch(IOException e){
                   throw new IOException("Fehler beim Öffnen: " + file);
            }
        }
    
    public String readLine()  throws IOException {
        String s = null;
   try{
                     s = in.readLine();
            }
            catch(IOException e){
                   throw new IOException("Fehler beim Lesen: " + e);
            }
       
        return s;
        }
```

edit: Sorry für die sch... Formatierung, hier gibt's leider kein CTRL+SHIFT+F


----------



## Crian (1. Jun 2011)

Als kleiner Beitrag - weil mir das genaue Verhalten nämlichnicht klar war:


```
public class RuntimeExceptions2 {

    public RuntimeExceptions2() {
        System.out.println("1");
        a();
        System.out.println("5");
    }

    private void a() {
        System.out.println("2");
        b();
        System.out.println("4");
    }

    private void b() {
        System.out.println("3");
        throw new RuntimeException("auweia!");
    }

    public static void main(String[] args) {
        new RuntimeExceptions2();
    }

}
```

Mit der Ausgabe


```
1
2
3
Exception in thread "main" java.lang.RuntimeException: auweia!
	at RuntimeExceptions2.b(RuntimeExceptions2.java:17)
	at RuntimeExceptions2.a(RuntimeExceptions2.java:11)
	at RuntimeExceptions2.<init>(RuntimeExceptions2.java:5)
	at RuntimeExceptions2.main(RuntimeExceptions2.java:21)
```

Das bedeutet, auch eine RuntimeException bricht darüberliegende Aufrufebenen ab. Genau wie "normale" Exceptions. Dann werde ich auch mal auf RuntimeExceptions und eine zentrale Behandlung umstellen. Alles was man nahe an der Fehlerquelle behandeln kann, kann man ja behandeln.


----------



## Spacerat (2. Jun 2011)

@hdi: Danke erst mal für das Nachreichen der Begriffe "checked" und "unchecked".

Meine subjektive Meinung über Exceptions in Java ist schlicht diese: In welch' anderer Programmiersprache wird noch zwischen 2 Sorten unterschieden? Ich kenn keine. Nur in Java wird man hier da und dort in die Pflicht genommen eine weiterzureichen oder abzufangen. Wir alle kennen diese hübschen Requester oder gar den Bluescreen, die einen nerven, wenn mal wieder ein Spiel oder was auch immer wegen so einer Ausnahme abstürzt. Dafür bekommt man dann vom Händler meistens mehr oder weniger schnell einen Bugfix, weil diese Ausnahme bei der Entwicklung gar nicht aufgefallen ist. Natürlich. Die Anwendung hat sich verabschiedet, aber als Entwickler sollte man durch seinen Code bzw. den des Teams soweit durchsteigen, dass man in Null Komma Wenig weis, woher diese Ausnahme kommt und genau dann sollte man sie erst abfangen und behandeln müssen. Da man in Java des öfteren völlig sinnfrei dafür in die Pflicht genommen wird, InetAddress von localhost ist wohl das beste Beispiel, sollte man sich vllt. mal ernsthaft Gedanken darüber machen ob *checked Exceptions* wirklich eine wahnsinnig tolle Idee waren, während es an anderer Stelle als unkonventionell, wenn nicht sogar als Designfehler gilt, *unchecked Exceptions* abzufangen, womit man am Ende wieder bei den selben dusseligen Nervrequestern und Bluescreens landet, die wir bereits aus anderen Sprachen kennen.
Fazit: *checked Exceptions* -> grober Unfug; Abfangen und Behandeln von *unchecked Exceptions* -> durchaus sinnvoll

@Edit: Okay... Bluescreens müssten in Java wohl oder übel "simuliert" werden :lol:


----------

