~Java4Beginners~
~Java4Beginners~

try-catch

Es gibt verschiedene Möglichkeiten zum Abfangen von Fehlern.

    /**
     * Dividiert 2 Zahlen miteinander
     * @param a erster int-Wert
     * @param b zweiter int-Wert
     * @return Ergebnis der Division a/b
     */
    static int division(int a, int b)
    {
            return a/b;
    }
Diese Methode dividiert 2 int-Zahlen und gibt das Ergebnis dieser int-Division zurück. Was passiert allerdings, wenn b den Wert 0 übergeben bekommt.

Auch hier wird eine Exception geworfen. Wie wir allerdings sehen können, tritt bzw. kann diese Exception an 2 Stellen auftreten. Geworfen wird die Exception innerhalb der Methode und an die aufrufende Methode, in unserem Falle die main-Methode weitergegeben.

Wir können diesen bekannten Fehler "Division durch 0" abfangen, in dem wir innerhalb unserer Divisions-Methode eine if-Abfrage starten, welche eine Berechnung nur zulässt, wenn b ungleich 0 ist. Die Idee scheint zwar gut, allerdings haben wir ein Problem. Wir können das Programm nicht compilieren, weil die Methode einen return-Wert verlangt, welcher bei dem Fall b = 0 nicht erfolgen würde.

Somit fällt diese Form schon mal weg. Es wäre nur denkbar, wenn wir die Methode komplett umschreiben.

Dies funktioniert wunderbar, allerding besteht das Problem, dass wir in unserer Main-Methode den String dann erst wieder zu einer Integer-Zahl parsen müssen.

Die feine programmiertechnische Lösung ist, dass wir den Aufruf in eine try-catch()-Anweisung packen. Es soll versucht werden, die 2 Zahlen zu dividieren, wenn dies zu einer Ausnahme führt, soll das Programm sich nicht aufhängen.

Wie man erkennen kann, kommt es zu keinem Programmabbruch mehr. Die geworfene Exception wurde aufgefangen, die Fehlermeldung ausgegeben und die anschließenden Anweisungen wurden ausgeführt.

try

In den try-Block packen wir die Anweisung, welche die Exception werfen könnte. Bei einigen Anweisungen werden wir schon durch die Entwicklungsumgebung gezwungen eine Exceptionbehandlung durchzuführen, bei anderen Anweisungen hilft uns die Erfahrung.

In unserem Beispiel haben wir die Division durch 0 behandelt. Wenn wir das Programm weiterentwickeln und das Programm dynamisch gestalten, werden bei den Benutzereingaben ebenfalls Ausnahmesituationen auftreten können. Es wird ein int-Wert erwartet, der Nutzer gibt aber eine Gleitkommazahl ein, oder einen Text, usw. Im Laufe der Programmierlaufbahn werden Sie immer wieder auf Fehler stoßen, die Sie noch gar nicht bedacht haben.

catch

catch (Exceptionklasse Bezeichner)

Im Bezeichner wird die Meldung der Exception abgelegt, welche wir über eine System.err.println() auf die Konsole ausgeben können. Andere Möglichkeit wäre es, die Fehlermeldung in einer Errorlog-Datei abzuspeichern.

Es ist nicht möglich in einer catch-Anweisung mehrere spezifische Exceptions abzufangen, allerdings können wir mehrere Catch-Blöcke hintereinander setzen.

Um die Division dynamisch zu gestalten, werden die zwei int-Werte nun über die Konsole abgefragt. Bei der Eingabe wird allerding anstatt einer int-Zahl eine Kommazahl eingegeben. Obwohl sich die Konsoleneingabe innerhalb des try-Blockes befindet, kommt es trotzdem zum Programmabbruch.

Um diese geworfene Exception mit abzufangen, werden wir einen zweiten Catch-Block anfügen, welcher die neu aufgetretene Exception abfängt.

multicatch

Eine weitere Möglichkeit ist die Verwendung eines Multicatch, wenn mehrere Exception-Klassen betroffen sind.

Allerdings ist der Multicatch nur sinnvoll, wenn die vorgegebne Exception-Meldung ausgegeben werden soll. Sollen eigene Fehlertexte ausgegeben werden, wird nichts anderes über bleiben, als mehrere Catch-Blöcke hintereinander zu setzen, welche die eigenen Fehlerausgaben vornimmt.

        catch (ArithmeticException e)
        {
            System.err.println("Division durch 0 nicht möglich");
        }
        catch (InputMismatchException e)
        {
            System.err.println("Es wurde kein int-Wert eingegeben");
        }
Wir erreichen zwar, dass mit try-catch kein Programmabbruch erfolgt, allerdings wird dadurch nicht ermöglicht, dass z. B. ein neuer Versuch einer Zahleneingabe gestartet wird. Dieses muss weiterhin über Kontrollstrukturen abgefangen werden.

finally

Im Anschluss an die catch-Blöcke kann noch ein finally-Block gesetzt werden. Egal ob eine Exception geworfen wird oder nicht, der finally-Block wird immer abgearbeitet.

Beispielprogramm


import java.util.InputMismatchException;
import java.util.Scanner;

/**
 * Beispiele für den Umgang mit Exceptions
 * @author Markus Badzura
 */
public class Exceptionhandling 
{
    static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) 
    {
//        System.out.println(7/0);
//        System.out.println("fertig")
        int a = 0;
        int b = 0;
        try
        {
            System.out.print("Zahl a: ");
            a = sc.nextInt();
            System.out.print("Zahl b: ");
            b = sc.nextInt();            
            System.out.println(division(a,b));
        }
        catch (ArithmeticException e)
        {
            System.err.println("Division durch 0 nicht möglich");
        }
        catch (InputMismatchException e)
        {
            System.err.println("Es wurde kein int-Wert eingegeben");
        }
        finally
        {
            System.out.println("Alle Exceptions abgearbeitet");
        }
        System.out.println("Programmende");
    }
    
    /**
     * Dividiert 2 Zahlen miteinander
     * @param a erster int-Wert
     * @param b zweiter int-Wert
     * @return Ergebnis der Division a/b
     */
    static int division(int a, int b)
    {
            return a/b;
    }
    
    /**
     * Dividiert 2 Zahlen miteinander
     * @param a erster int-Wert
     * @param b zweiter int-Wert
     * @return String mit dem Ergebnis oder Division durch 0
     */
    static String division1(int a, int b)
    {
        if (b!=0)
            return String.valueOf(a/b);
        else
            return "Division durch 0";
    } 
}
nach oben Java4Beginners -- Seitenversion 1.0 -- Stand: 2017-05-17