Heute widme ich mich folgender Fragestellung:

  • Wie funktioniert Try/Catch in Java?
  • Try und Catch Blöcke in Java
  • Exceptions mit Try und Catch in Java
  • Tutorial Try-Catch in Java
  • Try Catch Finally Java
  • Beispiel Try Catch Java

Das Try-Catch Kommando umschliesst einen Codeabschnitt und wird dafür verwendet mögliche Fehler (exceptions) innerhalb dieses Codeabschnittes abzufangen, sodass man darauf reagieren kann. Folgend ist die generelle Syntax dargestellt:

    try {
        // code der gesichert laeuft
    } catch (ExceptionKlassenname variablenname) {
        // Fehlerbehandlung
    }

Die Try-Catch Anweisung besteht aus vier Teilen. Der Block der von “try” eingeschloßen wird läuft gesichert ab kann möglicher Weise die Exception werfen die wir abfangen wollen. Die Fehlerbehandlung findet innerhalb des Catch-blockes statt. Der Exception Klassenname beschreibt den Fehler auf den wir reagieren wollen. Der Variablenname benennt die Exception innerhalb des Catch-blockes, sodass entsprechend der Exception innerhalb des Catch-blockes reagiert werden kann.

Wenn die abgefangene Exception innerhalb des Try-blockes geworfen wird, so springt die Codeausführung direkt in den Catch-Block. Wenn die Exception nicht geworfen wird, wird der Catch-block nie aufgerufen.

Hier ist ein Beispiel eines Programs, das versucht eine Datei in einem nichtexistierenden Verzeichnis zu erstellen und daher eine IOException wirft.

    String filename = "/nichtExistierendesVerzeichnis/meinDateinname";
    try {
        // Erstelle die Datei
        new File(filename).createNewFile();
    } catch (IOException e) {
        // Gib die Fehlermeldung aus die aufgetreten ist
        System.out.println("Konnte die Datei "+filename+
             " nicht erstellen:\n"+e.getMessage());
    }
    // Ausführung des Programmes wird hier fortgesetzt.

Hier ist die Ausgabe:

    Konnte die Datei /nichtExistierendesVerzeichnis/meinDateinname nicht erstellen: 
    The system cannot find the path specified

Es ist möglich mehr als einen Exception Handler zu definieren. Die Enception Handler werden von oben nach unten abgearbeitet. Wenn eine Exception auftritt, wird jeder Exception-Handler von oben nach unten überprüft ob er für die Exception zuständig ist. Der erste zutreffende Handler wird ausgeführt.

Das folgende Beispiel registriert einen Namen in einer Website. Der Beispielcode can zwei Arten von Exceptions werfen: eine wenn die URL invalide ist (MalformedURLException) und eine andere wenn auf die Webpage nicht zugegriffen werden kann. Das Beispiel verwendet eine ungültige URL, sodass eine MalformedURLException geworfen wird.

    // in dieser URL wurde absichtlich das http weggelassen
    String urlStr = "schabby.de:80/register=johannes";
    try {
        // lade von URL
        URL url = new URL(urlStr);
        InputStream is = url.openStream();
        is.close();
    } catch (MalformedURLException e) {
        // gib Fehlermeldung aus
        System.out.println("Fehlerhafte URL "+urlStr+": "+e.getMessage());
    } catch (IOException e) {
        // Gib Fehlermeldung aus
        System.out.println("konnte "+urlStr+" nicht oeffnen: "+e.getMessage());
    }

Hier ist die Ausgabe des Programs:


    Fehlerhafte URL Invalid URL schabby.de:80/register=johannes: no protocol: schabby.de:80/register=johannes

Folgende ist das selbe Beispiel mit korrekter URL angegeben. Die URL zeigt jedoch auf eine nichtexistierende Webseite, sodass dieses Mal eine IOException geworfen wird.

    urlStr = "http://schabby-gnagnagnang.de:80/register=johannes";
    try {
        // lade von URL
        URL url = new URL(urlStr);
        InputStream is = url.openStream();
        is.close();
    } catch (MalformedURLException e) {
        // gib Fehlermeldung aus
        System.out.println("Fehlerhafte URL "+urlStr+": "+e.getMessage());
    } catch (IOException e) {
        // Gib Fehlermeldung aus
        System.out.println("konnte "+urlStr+" nicht oeffnen: "+e.getMessage());
    }

Das Program gibt folgenden Output:

     konnte http://schabby-gnagnagnang.de:80/register=johannes nicht oeffnen: Connection refused: connect

Wenn eine Exception auftritt, wird sie mit allen angegebenen Exceptions in den Catch-blöcken mit Hilfe des instanceof Operators verglichen. Das bedeutet, wenn ein Handler für eine Exceptionklasse E angegeben wird, wird jede Exception die entweder vom Typ E ist oder eine Subklasse von E ist gehandelt.

Im folgenden Beispiel werden beide Exceptiontypen (MalformedURLException und IOException) unter der Oberklasse Exception vereinheitlicht und gehandelt.


    urlStr = "http://schabby-gnagnagnang.de:80/register=johannes";
    try {
        // lade von URL
        URL url = new URL(urlStr);
        InputStream is = url.openStream();
        is.close();
    } catch (Exception e) {
        // gib die Fehlermeldung aus
        System.out.println("problem beim laden von "+urlStr+": "+e.getMessage());
    }

Hier ist die Ausgabe:

    problem beim laden von http://schabby-gnagnagnang.de:80/register=johannes: Connection refused: connect

Wenn eine Exception auftritt die keinen passenden Handler hat, wird die Exception im Funktionsaufruffluss nach oben gereicht bis sie in einem entsprechenden try-catch Block abgefangen wird. Wenn kein try-catch Block zutrifft, schlägt die Exception bis auf die obererste Funktionseben durch und beendet den Thread in dem die Exception aufgetreten ist.

Im folgenden Beispiel provozieren wir eine Nullpointerexception die das Program zu absturz bringt da wir sie nicht in einem catch-block abfangen. Man spricht in solch einem Fall auch von einer uncaught Exception.

    // setze string to null um Nullpointerexception zu provozieren
    urlStr = null;
    try {
        int len = urlStr.length(); // verursacht Nullpointerexception
        URL url = new URL(urlStr);
    } catch (MalformedURLException e) {
        // gib Fehlermeldung aus
        System.out.println("Fehlerhafte URL "+urlStr+": "+e.getMessage());
    }

Das Ergbnis ist eine uncaught exception die das Program zum absturz bringt. Netter Weise gibt Java den Stacktrace aus, sodass man nachvollziehen kann wo der Fehler auftrat.

    Exception in thread "main" java.lang.NullPointerException
            at MeineKlasse.meineMethode(MeineKlasse.java:162)

Try-Catch Finally

Das nächste Level wollen wir dem Verständnis des finally Blocks erklimmen. Der finally Block wird einfach an das Ende der Try-Catch Blöcke gehängt. Seine Semantik ist einfach: Der finally Block wird IMMER ausgeführt, ganz egal ob im Try-Block eine Exception geworfen wurde oder nicht. Im Outline sieht das so aus:

    try {
        // code der gesichert laeuft
    } catch (ExceptionKlassenname variablenname) {
        // Fehlerbehandlung
    } finally {
        // wird in jedem Fall ausgeführt
    }

Das finally-Block ist inbesondere dann sinnvoll, wenn man einen Ursprungszustand wieder herstellen oder aufräumen muss. So eignet sich z.B. der finally Block sehr gut um Datein wieder zu schließen oder Sockets zu droppen.

Categories: Java

13 Comments

yoursurprise-bellatio-3 · December 10, 2011 at 5:06 pm

Hi there would you mind stating which blog platform you’re working with? I’m going to start my own blog in the near future but I’m having a difficult time selecting between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your design seems different then most blogs and I’m looking for something unique. P.S Apologies for being off-topic but I had to ask!

    schabby · December 10, 2011 at 6:20 pm

    Hi, I am using the classical WordPress. If you inspect the HTML, you find the line which reveals as well that I am using common WordPress.

Vijay · February 10, 2012 at 9:19 pm

Fair point, you do end up hvaing to duplicate code. Having a finally clause would be good. Using __destruct() to clean up resources can be handy, but sometimes it can be a long time after the object goes out of scope before this is called. I believe earlier version of PHP didn’t call it until script shutdown. For web requests this doesn’t matter (they are very short by nature), but for long running processes this may cause problems. Just something to be aware of.Maybe I should think of a better example – I just wanted to illustrate that you can re-throw Exceptions

FibreFoX · June 6, 2012 at 5:09 pm

@Vijay: this here is java, not php, ans in php you should call unset for handling memory, but be aware of optimization because of the all mighty garbage-collector.

back to topic (in german):

Sehr schöne Beispiele, ein klassischer Fall ist auch alles, was mit “File” zu tun hat, denn gerade .close() ist nervig wenn man es einpacken muss (deswegen habe ich mir kleine Helfer gebaut, damit ich keinen Code doppelt schreiben muss und am Ende doch in eine NullPointerException renne).

Gerade für Anfänger ist das sehr gut verständlich, allerdings sollte auch erwähnt sein, dass im FINALLY auch Datenbank-Sachen wie Roleback oder Commit sehr oft enthalten sind, oder aber das verhalten von einem Return im catch-bereich in kombination von einem Return im Finally.

Xesaphos · July 16, 2012 at 8:36 am

Super, danke. c:

NanTong · July 30, 2012 at 1:27 am

Sehr gute Erklärung, nur treten bei mir folgende Fehler auf:
1) Eclípse erwartet beim “catch” Befehl einen Identifier. was genau ist da gefragt?
2) laut Eclipse muss UNBEDINGT finally benutzt werden. ist das so?

    schabby · July 30, 2012 at 3:06 pm

    Hi!

    Hmm, das klingt merkwürdig. Mir scheint, da versteift sich Eclipse auf “best practice”. Es _muss_ meines Wissens kein finally verwendet werden und das ist öfters auch garnicht anwendbar. Du könntest ja einfach einen leeren finally Block immer dranpacken, was Quatsch wäre.

    Was für eine Eclipse-Version verwendest Du? Magst Du Deinen Code hier mal posten, damit ich einen Blick darauf werfen kann?

    Johannes

Kara · May 7, 2013 at 1:26 pm

Pefekte Erklährung^^. Ich wollte was wissen, habs gegoogelt und komme gleich auf so einen schön formulierten sachlich korrekten Blog und muss nich stundenlang im I-net suchen bis ich weiss was ich wissen wollte. weiter so XD

Nerdigoa · May 27, 2013 at 4:04 pm

Ich versteh ddie STelle mit dem PC nicht. Wie geht der denn an?
Ich bekomm auch als kein Internet

Nerdigoa · May 27, 2013 at 4:05 pm

Ey scheisse, ich glaube ich hab da Internet gelöscht 😮

Falko · May 13, 2016 at 1:08 am

Danke für diesen Beitrag!
Die Erklärung hat mir wunderbar weiter geholfen!

Styx · July 16, 2016 at 2:25 pm

@ 6. NanTong
In Eclipse kannst du einstellen was es erwartet. Zb ob bei if/while etc immer alles in {} gepackt werden muss oder eben sachen wie das mit dem finaly. kurz du kannst diese meldung (gelbes dreieck mit !) abschalten. nur wenn in dem dreieck noch ein rotes zeichen ist musst du was ändern das ist dann nämlich ein fehler. alles andere sind wie gesagt hinweise oder meldungen die du abstellen kannst.

3434re · February 22, 2018 at 11:46 am

naja ich kanns besser 😉

Leave a Reply

Your email address will not be published. Required fields are marked *