CodeGym/Java-Blog/Random-DE/Ausnahmen in Java
Autor
Alex Vypirailenko
Java Developer at Toshiba Global Commerce Solutions

Ausnahmen in Java

Veröffentlicht in der Gruppe Random-DE
Hallo! In der heutigen Lektion sprechen wir über Java-Ausnahmen. Der Alltag ist voller Situationen, mit denen wir nicht rechnen. Sie stehen beispielsweise morgens zur Arbeit auf und suchen nach dem Ladegerät für Ihr Telefon, können es aber nirgendwo finden. Sie gehen zum Duschen auf die Toilette und stellen fest, dass die Rohre gefroren sind. Sie steigen in Ihr Auto, aber es springt nicht an. Ein Mensch kann solche unvorhergesehenen Umstände recht leicht bewältigen. In diesem Artikel versuchen wir herauszufinden, wie Java-Programme damit umgehen.

Was ist eine Java-Ausnahme?

In der Programmierwelt werden Fehler und unvorhergesehene Situationen bei der Ausführung eines Programms als Ausnahmen bezeichnet. In einem Programm können Ausnahmen aufgrund ungültiger Benutzeraktionen, unzureichendem Speicherplatz oder Verlust der Netzwerkverbindung mit dem Server auftreten. Ausnahmen können auch durch Programmierfehler oder falsche Verwendung einer API entstehen. Anders als Menschen in der realen Welt muss ein Programm genau wissen, wie es mit diesen Situationen umgeht. Zu diesem Zweck verfügt Java über einen Mechanismus, der als Ausnahmebehandlung bezeichnet wird.

Ein paar Worte zu Schlüsselwörtern

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 einen Codeblock, in dem Ausnahmen behandelt werden;
  • final – definiert einen optionalen Codeblock, der, falls vorhanden, unabhängig von den Ergebnissen des try-Blocks ausgeführt wird.
Diese Schlüsselwörter werden verwendet, um spezielle Konstrukte im Code zu erstellen: try{}catch , try{}catch{}finally , try{}finally{} .
  • throw – wird verwendet, um eine Ausnahme auszulösen;
  • throws – wird in der Methodensignatur 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:
// This method reads a string from the keyboard

public String input() throws MyException { // Use throws to warn
// that the method may throw a MyException
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
// We use a try block to wrap code that might create an exception. In this case,
// the compiler tells us that the readLine() method in the
// BufferedReader class might throw an I/O exception
    try {
        s = reader.readLine();
// We use a catch block to wrap the code that handles an IOException
    } catch (IOException e) {
        System.out.println(e.getMessage());
// We close the read stream in the finally block
    } finally {
// An exception might occur when we close the stream if, for example, the stream was not open, so we wrap the code in a try block
        try {
            reader.close();
// Handle exceptions when closing the read stream
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// We've decided that an empty string will prevent our program from working properly. For example, we use the result of this method to call the substring(1, 2) method. Accordingly, we have to interrupt the program by using throw to generate our own MyException exception type.
        throw new MyException("The string cannot be empty!");
    }
    return s;
}

Warum brauchen wir Ausnahmen?

Schauen wir uns ein Beispiel aus der realen Welt an. Stellen Sie sich vor, dass ein Abschnitt einer Autobahn über eine kleine Brücke mit begrenzter Tragfähigkeit verfügt. Wenn ein Auto darüberfährt, das schwerer ist als das zulässige Gewicht der Brücke, kann die Brücke einstürzen. Die Situation für den Fahrer würde, gelinde gesagt, zur Ausnahmesituation werden. Um dies zu vermeiden, installiert die Transportabteilung Warnschilder auf der Straße, bevor etwas schief geht. Wenn ein Fahrer das Warnschild sieht, vergleicht er das Gewicht seines Fahrzeugs mit dem Höchstgewicht für die Brücke. Ist das Fahrzeug zu schwer, wählt der Fahrer eine Umgehungsroute. Erstens ermöglichte die Transportabteilung Lkw-Fahrern, ihre Route bei Bedarf zu ändern, zweitens warnte sie die Fahrer vor den Gefahren auf der Hauptstraße und drittens warnte sie die Fahrer, dass die Brücke unter bestimmten Bedingungen nicht benutzt werden dürfe. Ausnahmen in Java - 2Die Möglichkeit, Ausnahmesituationen in einem Programm zu verhindern und aufzulösen, sodass es weiterhin ausgeführt werden kann, ist einer der Gründe für die Verwendung von Ausnahmen in Java. Mit dem Ausnahmemechanismus können Sie Ihren Code (API) auch vor missbräuchlicher Verwendung schützen, indem Sie alle Eingaben validieren (überprüfen). Stellen Sie sich nun vor, Sie wären für eine Sekunde die Transportabteilung. Zunächst müssen Sie wissen, an welchen Stellen Autofahrer mit Problemen rechnen müssen. Zweitens müssen Sie Warnschilder erstellen und installieren. Und schließlich müssen Sie Umleitungen vorsehen, wenn auf der Hauptstrecke Probleme auftreten. In Java funktioniert der Ausnahmemechanismus auf ähnliche Weise. Während der Entwicklung verwenden wir einen Try- Block, um „Ausnahmebarrieren“ um gefährliche Codeabschnitte zu errichten. Wir stellen „Backup-Routen“ mithilfe eines Catch {} bereit.Block, und wir schreiben Code, der auf jeden Fall in einem „ finally{}“ -Block ausgeführt werden sollte. Wenn wir keine „Backup-Route“ bereitstellen können oder dem Nutzer ein Wahlrecht einräumen wollen, müssen wir ihn zumindest vor der Gefahr warnen. Warum? Stellen Sie sich die Empörung eines Autofahrers vor, der, ohne ein einziges Warnschild zu sehen, eine kleine Brücke erreicht, die er nicht überqueren kann! Beim Programmieren können wir beim Schreiben unserer Klassen und Methoden nicht immer vorhersehen, wie sie von anderen Entwicklern verwendet werden könnten. Daher können wir den zu 100 % korrekten Weg zur Lösung einer Ausnahmesituation nicht vorhersehen. Dennoch gehört es zum guten Ton, andere vor möglichen Ausnahmesituationen zu warnen. Der Ausnahmemechanismus von Java ermöglicht uns dies mit den WürfenSchlüsselwort – im Wesentlichen eine Erklärung, dass das allgemeine Verhalten unserer Methode das Auslösen einer Ausnahme umfasst. Daher weiß jeder, der die Methode verwendet, dass er oder sie Code schreiben sollte, um Ausnahmen zu behandeln.

Andere vor „Ärger“ warnen

Wenn Sie nicht vorhaben, Ausnahmen in Ihrer Methode zu behandeln, aber andere vor möglichen Ausnahmen warnen möchten, verwenden Sie das Schlüsselwort throws . Dieses Schlüsselwort in der Methodensignatur bedeutet, dass die Methode unter bestimmten Bedingungen eine Ausnahme auslösen kann. Diese Warnung ist Teil der Methodenschnittstelle und ermöglicht es den Benutzern, ihre eigene Ausnahmebehandlungslogik zu implementieren. Nach Auslösungen geben wir die Arten der ausgelösten Ausnahmen an. Diese stammen normalerweise von der Exception -Klasse von Java ab . Da Java eine objektorientierte Sprache ist, sind alle Ausnahmen Objekte in Java. Ausnahmen in Java - 3

Ausnahmehierarchie

Wenn während der Ausführung eines Programms ein Fehler auftritt, erstellt die JVM ein Objekt des entsprechenden Typs aus der Java-Ausnahmehierarchie – einer Reihe möglicher Ausnahmen, die von einem gemeinsamen Vorfahren abstammen – der Throwable- Klasse . Wir können außergewöhnliche Laufzeitsituationen in zwei Gruppen einteilen:
  1. Situationen, in denen sich das Programm nicht erholen und den normalen Betrieb nicht fortsetzen kann.
  2. Situationen, in denen eine Genesung möglich ist.
Die erste Gruppe umfasst Situationen mit einer Ausnahme, die von der Error- Klasse abstammt . Hierbei handelt es sich um Fehler, die aufgrund einer JVM-Fehlfunktion, eines Speicherüberlaufs oder eines Systemfehlers auftreten. Sie weisen in der Regel auf schwerwiegende Probleme hin, die nicht durch Software behoben werden können. In Java wird die Möglichkeit solcher Ausnahmen vom Compiler nicht überprüft, daher werden sie als ungeprüfte Ausnahmen bezeichnet. Zu dieser Gruppe gehören auch RuntimeExceptions, bei denen es sich um Ausnahmen handelt, die von der Ausnahme abstammenKlasse und werden von der JVM zur Laufzeit generiert. Sie werden häufig durch Programmierfehler verursacht. Diese Ausnahmen werden zur Kompilierungszeit auch nicht aktiviert (deaktiviert), sodass Sie keinen Code schreiben müssen, um sie zu behandeln. Die zweite Gruppe umfasst Ausnahmesituationen, die beim Schreiben des Programms vorhersehbar sind (und daher sollten Sie Code schreiben, um mit ihnen umzugehen). Solche Ausnahmen werden als geprüfte Ausnahmen bezeichnet. Wenn es um Ausnahmen geht, besteht der Großteil der Arbeit eines Java-Entwicklers darin, solche Situationen zu behandeln.

Eine Ausnahme erstellen

Wenn ein Programm ausgeführt wird, werden Ausnahmen entweder von der JVM oder manuell mithilfe einer Throw- Anweisung generiert. Wenn dies geschieht, wird ein Ausnahmeobjekt im Speicher erstellt, der Hauptablauf des Programms unterbrochen und der Ausnahmehandler der JVM versucht, die Ausnahme zu behandeln.

Ausnahmebehandlung

In Java erstellen wir Codeblöcke, in denen wir die Notwendigkeit einer Ausnahmebehandlung mithilfe der Konstrukte try{}catch , try{}catch{}finally und try{}finally{} antizipieren. Wenn in einem Try-Ausnahmen in Java - 4 Block eine Ausnahme ausgelöst wird , sucht die JVM im nächsten Catch- Block nach einem geeigneten Ausnahmehandler . Wenn ein Catch- Block über den erforderlichen Ausnahmehandler verfügt, wird die Kontrolle an ihn übergeben. Wenn nicht, sucht die JVM weiter unten in der Kette der Catch- Blöcke, bis der entsprechende Handler gefunden wird. Nach der Ausführung eines Catch- Blocks wird die Steuerung an den optionalen Final- Block übergeben . Wenn ein geeigneter FangWenn der Block nicht gefunden wird, stoppt die JVM das Programm und zeigt den Stack-Trace (den aktuellen Stapel der Methodenaufrufe) an, nachdem sie zunächst den Final- Block (falls vorhanden) ausgeführt hat. 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 print method: " + 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 handled. The program will continue");
            }
            finally {
                System.out.println("Inside finally block");
            }
            System.out.println("The program is running...");
            System.out.println("-----------------");
        }

    }
    }
Hier sind die Ergebnisse der Hauptmethode :
Inside print method: first step
Inside finally block
The program is running...
-----------------
Exception: s is null!
Exception handled. The program will continue
Inside finally block
The program is running...
-----------------
Inside print method: second step
Inside finally block
The program is running...
-----------------
Das „finally“ wird normalerweise verwendet, um alle Streams zu schließen und alle in einem Try- Block geöffneten/zugewiesenen Ressourcen freizugeben. Allerdings ist es beim Schreiben eines Programms nicht immer möglich, die Schließung aller Ressourcen im Auge zu behalten. Um uns das Leben zu erleichtern, bieten Java-Entwickler das Try-with-Resources- Konstrukt an, das automatisch alle in einem Try- Block geöffneten Ressourcen schließt. Unser erstes Beispiel kann mit try-with-resources umgeschrieben werden :
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 ("The string cannot be empty!");
    }
    return s;
}
Dank der in Version 7 eingeführten Java-Funktionen können wir auch das Abfangen heterogener Ausnahmen in einem Block kombinieren, wodurch der Code kompakter und lesbarer wird. 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("The string cannot be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

Das Endergebnis

Durch die Verwendung von Ausnahmen in Java können Sie Ihre Programme robuster machen, indem Sie „Backup-Routen“ erstellen, Catch-Blöcke verwenden, um den Hauptcode vom Ausnahmebehandlungscode zu trennen, und Throws verwenden, um die Verantwortung für die Ausnahmebehandlung auf denjenigen zu verlagern, der Ihre Methode verwendet .
Kommentare
  • Beliebt
  • Neu
  • Alt
Du musst angemeldet sein, um einen Kommentar schreiben zu können
Auf dieser Seite gibt es noch keine Kommentare