JavaRush /Java-Blog /Random-DE /Ausnahmen in Java (Java-Ausnahme)

Ausnahmen in Java (Java-Ausnahme)

Veröffentlicht in der Gruppe Random-DE
Im Alltag passieren manchmal Situationen, mit denen wir nicht gerechnet haben. Sie stehen beispielsweise morgens zur Arbeit auf und suchen nach einem Ladegerät für Ihr Telefon, aber es gibt keines. Sie gehen auf die Toilette, um Ihr Gesicht zu waschen – das Wasser ist abgestellt. Ich stieg ins Auto und es sprang nicht an. Aber solche unvorhergesehenen Situationen kann ein Mensch problemlos bewältigen. Wir werden in diesem Artikel versuchen herauszufinden, wie Java-Programme damit umgehen.

Was sind Ausnahmen Java

In der Programmierwelt wird das Auftreten von Fehlern und unerwarteten Situationen während der Programmausführung als Ausnahme bezeichnet. In einem Programm können Ausnahmen aufgrund falscher Benutzeraktionen, des Fehlens einer erforderlichen Ressource auf der Festplatte oder des Verlusts der Verbindung zum Server über das Netzwerk auftreten. Ausnahmen während der Programmausführung können auch durch Programmierfehler oder falsche Verwendung der API verursacht werden. Im Gegensatz zu unserer Welt muss das Programm klar wissen, was in einer solchen Situation zu tun ist. Java stellt hierfür einen Ausnahmemechanismus zur Verfügung.

Kurz zu den Schlüsselwörtern versuchen, fangen und schließlich werfen

Die Ausnahmebehandlung in Java basiert auf der Verwendung der folgenden Schlüsselwörter im Programm:
  • try – definiert einen Codeblock, in dem eine Ausnahme auftreten kann;
  • Catch – definiert den Codeblock, in dem die Ausnahme behandelt wird;
  • final – definiert einen Codeblock, der optional ist, aber falls vorhanden, trotzdem ausgeführt wird, unabhängig von den Ergebnissen des try-Blocks.
Diese Schlüsselwörter werden verwendet, um spezielle Verarbeitungskonstrukte im Programmcode zu erstellen: try{}catch, try{}catch{}finally, try{}finally{}.
  • throw – wird verwendet, um eine Ausnahme auszulösen;
  • throws – werden in Methodensignaturen verwendet, um zu warnen, dass die Methode möglicherweise eine Ausnahme auslöst.
Ein Beispiel für die Verwendung von Schlüsselwörtern in einem Java-Programm:
//Methode liest einen String von der Tastatur

public String input() throws MyException {//mit Würfen warnen,
// dass die Methode MyException auslösen kann
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
// im try-Block schließen wir den Code ein, in dem eine Ausnahme auftreten kann, in diesem
// wenn der Compiler uns mitteilt, dass die readLine()-Methode der Klasse
// BufferedReader löst möglicherweise eine E/A-Ausnahme aus
    try {
        s = reader.readLine();
// Im Catch-Block schließen wir den Code zur Behandlung der IOException-Ausnahme ein
    } catch (IOException e) {
        System.out.println(e.getMessage());
// Den Lesestream im „finally“-Block schließen
    } finally {
// Beim Schließen des Streams ist auch eine Ausnahme möglich, z. B. wenn er nicht geöffnet wurde, also „verpacken“ wir den Code in einen Try-Block
        try {
            reader.close();
// Ausnahmebehandlung beim Schließen des Lesestreams schreiben
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// Wir haben entschieden, dass ein leerer String die Arbeit unseres Programms in Zukunft stören könnte. Als Ergebnis dieser Methode müssen wir beispielsweise die Methode substring(1,2) aufrufen, sodass wir gezwungen sind, das Programm zu unterbrechen Ausführung mit der Generierung unseres Ausnahmetyps MyException mittels throw
        throw new MyException("String can not be empty!");
    }
    return s;
}

Warum brauchen wir einen Ausnahmemechanismus?

Schauen wir uns ein Beispiel aus der Praxis an. Stellen Sie sich vor, dass es auf einer Autobahn einen Abschnitt mit einer Notbrücke mit begrenzter Tragfähigkeit gibt. Wenn ein Fahrzeug über die Brücke fährt, dessen Masse die Tragfähigkeit der Brücke übersteigt, kann es zu einem Zusammenbruch kommen, und die Situation für den Fahrer kann gelinde gesagt zur Ausnahmesituation werden. Um dies zu verhindern, installiert der Straßendienst vorab Warnschilder auf der Straße. Der Fahrer des Fahrzeugs vergleicht anhand des Warnschilds das Gewicht seines Fahrzeugs mit dem für die Fahrt auf der Brücke zulässigen Gewicht. Bei Überschreitung nimmt er einen Umweg. Dank der Maßnahmen des Straßendienstes wurde den LKW-Fahrern erstens die Möglichkeit gegeben, ihre Route im Voraus zu ändern, zweitens wurden sie vor der Gefahr auf der Hauptroute gewarnt und schließlich wurden sie vor der Unmöglichkeit der Nutzung gewarnt die Brücke unter bestimmten Bedingungen.
Ausnahmen in Java - 2
Die Möglichkeit, eine Ausnahme in einem Programm zu verhindern und aufzulösen, damit es fortgesetzt werden kann, ist einer der Gründe für die Verwendung von Ausnahmen in Java. Der Ausnahmemechanismus ermöglicht es Ihnen außerdem, den von Ihnen geschriebenen Code (Programmierschnittstelle) vor Missbrauch durch den Benutzer zu schützen, indem eingehende Daten validiert (überprüft) werden. Jetzt lasst uns für eine Sekunde die Verkehrspolizei sein. Zunächst sollten Sie wissen, wo Autofahrer in Schwierigkeiten geraten können. Zweitens müssen Sie Warnschilder vorbereiten und anbringen. Schließlich müssen Sie für den Fall einer Gefahr auf der Hauptstrecke Umleitungswege vorsehen. In Java funktioniert der Ausnahmemechanismus auf ähnliche Weise. In der Programmentwicklungsphase „schützen“ wir gefährliche Codeabschnitte vor Ausnahmen mithilfe des try{}-Blocks, stellen „Backup“-Pfade mithilfe des Catch{}-Blocks bereit und im „finally{}“-Block schreiben wir Code, der im ausgeführt wird Programm für jedes Ergebnis. In den Fällen, in denen wir keinen „Notfallweg“ bereitstellen können oder die Wahl bewusst dem Nutzer überlassen wollen, müssen wir ihn zumindest auf die Gefahr hinweisen. Warum? Stellen Sie sich die Empörung eines Autofahrers vor, der eine Notbrücke erreicht, die nicht überquert werden kann, ohne unterwegs auf ein einziges Warnschild zu stoßen! Beim Programmieren können wir beim Schreiben unserer Klassen und Methoden nicht immer den Kontext ihrer Verwendung durch andere Entwickler in ihren Programmen vorhersehen, sodass wir den 100 % richtigen Weg zur Lösung der Ausnahmesituation nicht vorhersehen können. Gleichzeitig ist es eine gute Praxis, Benutzer unseres Codes vor der Möglichkeit einer Ausnahme zu warnen. Der Ausnahmemechanismus von Java ermöglicht uns dies durch die Verwendung von Würfen – im Wesentlichen durch die Deklaration des allgemeinen Verhaltens unserer Methode zum Auslösen einer Ausnahme, wodurch es dem Benutzer der Methode überlassen wird, Code zur Behandlung der Ausnahme in Java zu schreiben.

Warnung vor „Ärger“

Wenn Sie nicht vorhaben, eine Ausnahme in Ihrer Methode zu behandeln, Benutzer der Methode jedoch vor möglichen Ausnahmesituationen warnen möchten, verwenden Sie das Schlüsselwort throws. Dieses Schlüsselwort in einer Methodensignatur bedeutet, dass die Methode unter bestimmten Bedingungen eine Ausnahme auslösen kann. Diese Warnung ist Teil der Methodenschnittstelle und gibt dem Benutzer das Recht, die Implementierung des Ausnahmehandlers anzupassen. Nach Auslösungen geben wir die Art der ausgelösten Ausnahme an. Dies sind normalerweise Nachkommen der Java- Exception- Klasse . Da Java eine objektorientierte Sprache ist, sind alle Ausnahmen in Java Objekte.
Ausnahmen in Java - 3

Java-Ausnahmehierarchie

Wenn während der Programmausführung ein Fehler auftritt, erstellt die JVM-Laufzeit ein Objekt des erforderlichen Typs aus der Java-Ausnahmehierarchie – dem Satz möglicher Ausnahmen, die von einem gemeinsamen „Vorfahren“ – der Throwable-Klasse – geerbt wurden. Ausnahmesituationen, die in einem Programm auftreten, können in zwei Gruppen eingeteilt werden:
  1. Situationen, in denen die Wiederherstellung des weiteren normalen Programmbetriebs nicht möglich ist
  2. Eine Wiederherstellung ist möglich.
Die erste Gruppe umfasst Situationen, in denen von der Error- Klasse geerbte Ausnahmen auftreten . Hierbei handelt es sich um Fehler, die während der Programmausführung aufgrund eines JVM-Fehlers, eines Speicherüberlaufs oder eines Systemabsturzes auftreten. Sie weisen in der Regel auf schwerwiegende Probleme hin, die nicht mithilfe von Software behoben werden können. Diese Art von Ausnahme wird in Java in der Kompilierungsphase als ungeprüft eingestuft. Zu dieser Gruppe gehören auch RuntimeException – Ausnahmen, Erben der Exception- Klasse , die von der JVM während der Programmausführung generiert werden. Sie werden häufig durch Programmierfehler verursacht. Diese Ausnahmen werden auch zur Kompilierungszeit deaktiviert, sodass kein Code zu ihrer Behandlung geschrieben werden muss. Die zweite Gruppe umfasst Ausnahmesituationen, die beim Schreiben des Programms vorhergesehen werden und für die Verarbeitungscode geschrieben werden muss. Solche Ausnahmen werden geprüft. Der Großteil der Arbeit eines Java-Entwicklers im Umgang mit Ausnahmen besteht darin, solche Situationen zu bewältigen.

Eine Ausnahme erstellen

Während der Programmausführung wird von der JVM oder manuell mithilfe der throw- Anweisung eine Ausnahme ausgelöst . Dadurch wird ein Ausnahmeobjekt im Speicher erstellt und die Ausführung des Hauptprogrammcodes unterbrochen, während der JVM-Ausnahmehandler versucht, eine Möglichkeit zur Behandlung der Ausnahme zu finden.

Ausnahmebehandlung

Die Erstellung von Codeblöcken, für die wir eine Ausnahmebehandlung in Java bereitstellen, erfolgt im Programm mithilfe der Konstrukte try{}catch, try{}catch{}finally, try{}finally{}.
Ausnahmen in Java - 4
Wenn in einem Try-Block eine Ausnahme ausgelöst wird, wird im folgenden Catch-Block nach dem Ausnahmehandler gesucht. Wenn der Catch einen Handler für diese Art von Ausnahme enthält, wird die Kontrolle an ihn übergeben. Wenn nicht, sucht die JVM in der Kette der Methodenaufrufe nach einem Handler für diese Art von Ausnahme, bis ein geeigneter Catch gefunden wird. Nachdem der Catch-Block ausgeführt wurde, wird die Steuerung an einen optionalen Final- Block übergeben . Wenn kein geeigneter Catch-Block gefunden wird, stoppt die JVM die Programmausführung und zeigt einen Stapel von Methodenaufrufen an ( Stack Trace) , nachdem zuvor der Code des Final-Blocks ausgeführt wurde, falls vorhanden. Beispiel für die Ausnahmebehandlung:
public class Print {

     void print(String s) {
        if (s == null) {
            throw new NullPointerException("Exception: s is null!");
        }
        System.out.println("Inside method print: " + s);
    }

    public static void main(String[] args) {
        Print print = new Print();
        List list= Arrays.asList("first step", null, "second step");

        for (String s:list) {
            try {
                print.print(s);
            }
            catch (NullPointerException e) {
                System.out.println(e.getMessage());
                System.out.println("Exception was processed. Program continues");
            }
            finally {
                System.out.println("Inside bloсk finally");
            }
            System.out.println("Go program....");
            System.out.println("-----------------");
        }

    }
    }
Die Ergebnisse der Hauptmethode :
Inside method print: first step
Inside bloсk finally
Go program....
-----------------
Exception: s is null!
Exception was processed. Program continues
Inside bloсk finally
Go program....
-----------------
Inside method print: second step
Inside bloсk finally
Go program....
-----------------
Der Block finallywird normalerweise verwendet, um im Try-Block geöffnete Streams zu schließen oder um Ressourcen freizugeben. Allerdings ist es beim Schreiben eines Programms nicht immer möglich, den Überblick über die Schließung aller Ressourcen zu behalten. Um uns das Leben zu erleichtern, haben uns Java-Entwickler ein Konstrukt angeboten try-with-resources, das in einem Try-Block geöffnete Ressourcen automatisch schließt. Unser erstes Beispiel kann wie folgt umgeschrieben werden try-with-resources:
public String input() throws MyException {
    String s = null;
    try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
        s = reader.readLine();
   } catch (IOException e) {
       System.out.println(e.getMessage());
   }
    if (s.equals("")){
        throw new MyException ("String can not be empty!");
    }
    return s;
}
Dank der Fähigkeiten von Java können wir ab Version 7 auch das Abfangen verschiedener Ausnahmetypen in einem einzigen Block kombinieren, wodurch der Code kompakter und lesbarer wird. Zum Beispiel:
public String input() {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        s = reader.readLine();
        if (s.equals("")) {
            throw new MyException("String can not be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

Ergebnisse

Die Verwendung von Ausnahmen in Java ermöglicht es uns, die Fehlertoleranz des Programms durch die Verwendung von „Backup“-Pfaden zu erhöhen, die Logik des Hauptcodes vom Ausnahmebehandlungscode durch die Verwendung von Catch-Blöcken zu trennen und uns auch die Möglichkeit zu geben, zu delegieren Ausnahmebehandlung für den Benutzer unseres Codes mithilfe von Würfen.
Was gibt es sonst noch zu lesen:

Die 10 häufigsten Fragen zu Ausnahmen in Java

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION