Java-Ausnahmebehandlung

In Java ist die Ausnahmebehandlung ein wichtiges Programmierkonzept, das verwendet wird, um Fehler oder Ausnahmebedingungen zu behandeln, die während der Programmausführung auftreten können.

Ausnahmen sind einige Fehler in einem Programm, aber nicht alle Fehler sind Ausnahmen, und Fehler können manchmal vermieden werden.

Zum Beispiel, wenn in Ihrem Code ein Semikolon fehlt, dann ist die Ausgabe eine Fehlermeldungjava.lang.Error, wenn SieSystem.out.println(11/0)verwenden, dann wird, weil Sie0als Divisor verwenden, ausgelöstjava.lang.ArithmeticExceptioneine Ausnahme.

Es gibt viele Gründe für Ausnahmen, die üblicherweise die folgenden Kategorien umfassen:

  • Der Benutzer hat ungültige Daten eingegeben.
  • Die zu öffnende Datei existiert nicht.
  • Die Verbindung wird während der Netzwerkkommunikation unterbrochen, oder der JVM-Speicher läuft über.

Einige dieser Ausnahmen werden durch Benutzerfehler verursacht, einige durch Programmfehler und andere durch physische Fehler.

Um zu verstehen, wie die Java-Ausnahmebehandlung funktioniert, müssen Sie die folgenden drei Arten von Ausnahmen beherrschen:

  • Geprüfte Ausnahmen:Die repräsentativsten geprüften Ausnahmen sind Ausnahmen, die durch Benutzerfehler oder Probleme verursacht werden. Diese Ausnahmen zwingen Programmierer, sie zur Kompilierzeit zu behandeln. Wenn beispielsweise versucht wird, eine nicht vorhandene Datei zu öffnen, tritt eine Ausnahme auf, und diese Ausnahmen können zur Kompilierzeit nicht einfach ignoriert werden.

    Diese Art von Ausnahme wird normalerweise behandelt, indemtry-catch-Blöcke verwendet werden, um die Ausnahme abzufangen und zu behandeln, oder indemthrows-Klauseln verwendet werden, um Ausnahmen zu deklarieren, die eine Methode auslösen kann.

    try {
        // 可能会抛出异常的代码
    } catch (IOException e) {
        // 处理异常的代码
    }

    Oder:

    public void readFile() throws IOException {
        // 可能会抛出IOException的代码
    }
  • Laufzeitausnahmen:Diese Ausnahmen müssen zur Kompilierzeit nicht behandelt werden; sie werden normalerweise durch Fehler im Programm verursacht, wie NullPointerException, ArrayIndexOutOfBoundsException usw. Diese Art von Ausnahme kann optional behandelt werden, ist aber nicht obligatorisch.

    try {
        // 可能会抛出异常的代码
    } catch (NullPointerException e) {
        // 处理异常的代码
    }
  • Fehler:Fehler sind keine Ausnahmen, sondern Probleme außerhalb der Kontrolle des Programmierers. Fehler werden im Code normalerweise ignoriert. Wenn beispielsweise ein Stack-Überlauf auftritt, geschieht ein Fehler, und sie können auch zur Kompilierzeit nicht erkannt werden.

Java bietet die folgenden Schlüsselwörter und Klassen zur Unterstützung der Ausnahmebehandlung:

  • try: Wird verwendet, um einen Codeblock einzuschließen, der eine Ausnahme auslösen könnte.
  • catch: Wird verwendet, um Ausnahmen abzufangen und sie in einem Codeblock zu behandeln.
  • finally: Wird verwendet, um einen Codeblock zu enthalten, der ausgeführt werden muss, unabhängig davon, ob eine Ausnahme auftritt.
  • throw: Wird verwendet, um eine Ausnahme manuell auszulösen.
  • throws: Wird verwendet, um in einer Methodendeklaration die Ausnahmen anzugeben, die die Methode auslösen kann.
  • Exception-Klasse: Sie ist die Elternklasse aller Ausnahmeklassen und bietet Methoden zum Abrufen von Ausnahmeinformationen, wie z. B.getMessage()、printStackTrace()usw.

Exception-Klassenhierarchie

Alle Ausnahmeklassen sind Unterklassen, die von der Klasse java.lang.Exception erben.

Die Exception-Klasse ist eine Unterklasse der Throwable-Klasse. Neben der Exception-Klasse hat Throwable auch eine Unterklasse Error.

Java-Programme fangen Fehler normalerweise nicht ab. Fehler treten im Allgemeinen bei schwerwiegenden Ausfällen auf und liegen außerhalb des Bereichs der Behandlung durch Java-Programme.

Error wird verwendet, um Fehler anzugeben, die in der Laufzeitumgebung auftreten.

Zum Beispiel JVM-Speicherüberlauf. Im Allgemeinen können Programme sich nicht von Fehlern erholen.

Die Exception-Klasse hat zwei Hauptunterklassen: die IOException-Klasse und die RuntimeException-Klasse.

Unter den in Java integrierten Klassen (später erklärt) befinden sich die meisten der üblichen geprüften und ungeprüften Ausnahmen.


Java-integrierte Ausnahmeklassen

Die Sprache Java definiert einige Ausnahmeklassen im Standardpaket java.lang.

Unterklassen der standardmäßigen Laufzeit-Ausnahmeklasse sind die häufigsten Ausnahmeklassen. Da das Paket java.lang standardmäßig in alle Java-Programme geladen wird, können die meisten von Laufzeit-Ausnahmeklassen geerbten Ausnahmen direkt verwendet werden.

Java definiert auch einige andere Ausnahmen basierend auf verschiedenen Klassenbibliotheken. Die folgende Tabelle listet Javas ungeprüfte Ausnahmen auf.

Ausnahme Beschreibung
ArithmeticException Wird ausgelöst, wenn eine außergewöhnliche arithmetische Bedingung auftritt. Wenn beispielsweise eine ganze Zahl durch null geteilt wird, wird eine Instanz dieser Klasse ausgelöst.
ArrayIndexOutOfBoundsException Ausnahme, die ausgelöst wird, wenn mit einem ungültigen Index auf ein Array zugegriffen wird. Wenn der Index negativ oder größer oder gleich der Array-Größe ist, ist der Index ungültig.
ArrayStoreException Ausnahme, die ausgelöst wird, wenn versucht wird, ein Objekt des falschen Typs in ein Array von Objekten zu speichern.
ClassCastException Wird ausgelöst, wenn versucht wird, ein Objekt in eine Unterklasse umzuwandeln, von der es keine Instanz ist.
IllegalArgumentException Wird ausgelöst, um anzuzeigen, dass ein ungültiges oder unangemessenes Argument an eine Methode übergeben wurde.
IllegalMonitorStateException Wird ausgelöst, um anzuzeigen, dass ein Thread versucht hat, auf den Monitor eines Objekts zu warten oder andere Threads, die auf den Monitor eines Objekts warten, zu benachrichtigen, ohne selbst den Monitor zu besitzen.
IllegalStateException Signalisiert, dass eine Methode zu einem unzulässigen oder unpassenden Zeitpunkt aufgerufen wurde. Mit anderen Worten: Die Java-Umgebung oder Java-Anwendung befindet sich nicht im geeigneten Zustand, der für die angeforderte Operation erforderlich ist.
IllegalThreadStateException Ausnahme, die ausgelöst wird, wenn sich ein Thread nicht im geeigneten Zustand befindet, der für die angeforderte Operation erforderlich ist.
IndexOutOfBoundsException Wird ausgelöst, um anzuzeigen, dass eine Art von Index (z. B. für ein Array, einen String oder einen Vektor) außerhalb des gültigen Bereichs liegt.
NegativeArraySizeException Wird ausgelöst, wenn eine Anwendung versucht, ein Array mit einer negativen Größe zu erstellen.
NullPointerException Wenn eine Anwendung versucht,nullan einer Stelle zu verwenden, an der ein Objekt erforderlich ist, wird diese Ausnahme ausgelöst.
NumberFormatException Wird ausgelöst, wenn eine Anwendung versucht, eine Zeichenfolge in einen numerischen Typ zu konvertieren, die Zeichenfolge aber nicht in das entsprechende Format konvertiert werden kann.
SecurityException Eine vom Sicherheitsmanager ausgelöste Ausnahme, um eine Sicherheitsverletzung anzuzeigen.
StringIndexOutOfBoundsException Diese Ausnahme wird ausgelöst durch dieStringMethode, um anzuzeigen, dass der Index entweder negativ oder größer als die Länge der Zeichenfolge ist.
UnsupportedOperationException Wird ausgelöst, wenn die angeforderte Operation nicht unterstützt wird.

Die folgende Tabelle listet die von Java im Paket java.lang definierten geprüften Ausnahmeklassen auf.

Ausnahme Beschreibung
ClassNotFoundException Wird ausgelöst, wenn eine Anwendung versucht, eine Klasse zu laden, aber die entsprechende Klasse nicht finden kann.
CloneNotSupportedException Beim AufrufObjectdie Methode in dercloneKlasse zum Klonen eines Objekts, aber die Klasse des Objekts kann nicht implementierenCloneabledie Schnittstelle, wird diese Ausnahme ausgelöst.
IllegalAccessException Wird ausgelöst, wenn der Zugriff auf eine Klasse verweigert wird.
InstantiationException Beim Versuch,Classdie Methode in dernewInstancedie Klasse zu verwenden, um eine Instanz einer Klasse zu erstellen, aber das angegebene Klassenobjekt kann nicht instanziiert werden, weil es eine Schnittstelle oder eine abstrakte Klasse ist, wird diese Ausnahme ausgelöst.
InterruptedException Wird ausgelöst, wenn ein Thread von einem anderen Thread unterbrochen wird.
NoSuchFieldException Die angeforderte Variable existiert nicht.
NoSuchMethodException Die angeforderte Methode existiert nicht.

Exception-Methoden

Die folgende Liste enthält die wichtigsten Methoden der Klasse Throwable:

Nein. Methode und Beschreibung
1 public String getMessage()
Gibt detaillierte Informationen über die aufgetretene Ausnahme zurück. Diese Nachricht wird im Konstruktor der Klasse Throwable initialisiert.
2 public Throwable getCause()
Gibt ein Throwable-Objekt zurück, das die Ursache der Ausnahme darstellt.
3 public String toString()
Gibt eine kurze Beschreibung dieses Throwable zurück.
4 public void printStackTrace()
Gibt dieses Throwable und seinen Backtrace im Standardfehlerstream aus.
5 public StackTraceElement [] getStackTrace()
Gibt ein Array zurück, das den Stacktrace enthält. Das Element am Index 0 stellt die Spitze des Stapels dar, und das letzte Element stellt das untere Ende des Methodenaufruf-Stapels dar.
6 public Throwable fillInStackTrace()
Füllt den Stacktrace des Throwable-Objekts mit dem aktuellen Aufruf-Stacktrace und fügt ihn zu allen vorherigen im Stacktrace hinzu.

Ausnahmen abfangen

Verwenden Sie die Schlüsselwörter try und catch, um Ausnahmen abzufangen. Der try/catch-Codeblock wird an der Stelle platziert, an der eine Ausnahme auftreten kann.

Der Code innerhalb eines try/catch-Codeblocks wird als geschützter Code bezeichnet. Die Syntax für die Verwendung von try/catch lautet wie folgt:

try
{
   // 程序代码
}catch(ExceptionName e1)
{
   //Catch 块
}

Die catch-Klausel enthält eine Deklaration des abzufangenden Ausnahmetyps. Wenn eine Ausnahme im geschützten Code auftritt, wird der auf das try folgende catch-Block geprüft.

Wenn die auftretende Ausnahme im catch-Block enthalten ist, wird die Ausnahme an diesen catch-Block übergeben, auf die gleiche Weise, wie eine Methode ein Argument übergibt.

Beispiel

Im folgenden Beispiel wird ein Array mit zwei Elementen deklariert. Wenn der Code versucht, auf das dritte Element des Arrays zuzugreifen, wird eine Ausnahme ausgelöst.

Code der Datei ExcepTest.java:

//Dateiname: ExcepTest.java import java.io.*; public class ExcepTest{ public static void main(String args[]){ try{ int a[] = new int[2]; System.out.println("Zugriff auf Element drei:" + a[3]); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Ausnahme ausgelöst:" + e); } System.out.println("Außerhalb des Blocks"); } }

Die Ausgabe beim Kompilieren und Ausführen des obigen Codes ist wie folgt:

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block

Mehrere Catch-Blöcke

Die Situation, in der auf einen try-Block mehrere catch-Blöcke folgen, wird als mehrfaches Abfangen bezeichnet.

Die Syntax für mehrere Catch-Blöcke lautet wie folgt:

try{ //Code }catch(Ausnahmetyp1Name der Ausnahmevariable1){ //Code }catch(Ausnahmetyp2Name der Ausnahmevariablen2){ //Code }catch(Ausnahmetyp3Name der Ausnahmevariablen3){ //Code }

Das obige Code-Snippet enthält 3 catch-Blöcke.

Sie können eine beliebige Anzahl von catch-Blöcken nach einer try-Anweisung hinzufügen.

Wenn im geschützten Code eine Ausnahme auftritt, wird die Ausnahme an den ersten catch-Block weitergegeben.

Wenn der Datentyp der geworfenen Ausnahme mit ExceptionType1 übereinstimmt, wird sie hier abgefangen.

Wenn er nicht übereinstimmt, wird sie an den zweiten catch-Block weitergegeben.

Und so weiter, bis die Ausnahme abgefangen wird oder alle catch-Blöcke durchläuft.

Beispiel

Dieses Beispiel zeigt, wie mehrere try/catch verwendet werden.

try { file = new FileInputStream(fileName); x = (byte) file.read(); } catch(FileNotFoundException f) { // Nicht gültig! f.printStackTrace(); return -1; } catch(IOException i) { i.printStackTrace(); return -1; }

Multi-Catch für mehrere Ausnahmen

Ab Java 7 wurde eine prägnantere Syntax eingeführt – das kombinierte Abfangen mehrerer Ausnahmen, das es einem einzelnen catch-Block ermöglicht, mehrere Ausnahmen zu behandeln, die in keiner Vererbungsbeziehung zueinander stehen.

try {
    // 可能抛出多个不同类型异常的代码
} catch (异常类型1 | 异常类型2 | 异常类型3 异常变量) {
    // 统一处理
}

Hinweis:

  • ExceptionType1, ExceptionType2 usw. dürfen keine Vererbungsbeziehung zueinander haben; andernfalls tritt ein Kompilierungsfehler auf.
  • Der Name der Ausnahmevariable ist eine gemeinsame Referenzvariable für diese Ausnahmen, daher können Sie ihre spezifischen Methoden nicht innerhalb des catch-Blocks aufrufen.
  • Der Compiler leitet ab, dass der Typ dieser Ausnahmevariable die nächstgelegene gemeinsame Oberklasse dieser Ausnahmen ist (wie Exception oder IOException).

Wie im Folgenden, wo Ausnahmen nicht voneinander erben und sowohl SQLException als auch IOException geworfen werden können:

Beispiel

try {
    // Sowohl SQL- als auch IO-Ausnahmen können geworfen werden
    doSomething();
} catch (SQLException | IOException e) {
    System.out.println("Eine SQL- oder IO-Ausnahme ist aufgetreten!");
    e.printStackTrace();
}

Inkorrektes Beispiel (Über- und Unterklassen-Ausnahmen können nicht kombiniert werden):

// 错误写法!
catch (FileNotFoundException | IOException e) {
    // 会导致编译错误,因为 FileNotFoundException 是 IOException 的子类
}

FileNotFoundException ist eine Unterklasse von IOException, daher ist dieser Ansatz eigentlich unzulässig und verursacht einen Kompilierungsfehler.


throws/throw-Schlüsselwörter

In Java werden die Schlüsselwörterthrowundthrowsverwendet, um Ausnahmen zu behandeln.

throwDas Schlüsselwort wird verwendet, um eine Ausnahme im Code auszulösen, währendthrowsdas Schlüsselwort in der Methodendeklaration verwendet wird, um die Typen von Ausnahmen anzugeben, die ausgelöst werden können.

throw-Schlüsselwort

throwDas Schlüsselwort wird verwendet, um in der aktuellen Methode eine Ausnahme auszulösen.

Normalerweise, wenn der Code eine Bedingung erreicht, unter der er die normale Ausführung nicht fortsetzen kann, können Sie das Schlüsselwortthrowverwenden, um eine Ausnahme auszulösen, um den Aufrufer über den aktuellen Ausführungszustand des Codes zu informieren.

Zum Beispiel prüft die Methode im folgenden Code, ob num kleiner als 0 ist; wenn ja, wirft sie eine IllegalArgumentException.

Beispiel

public void checkNumber(int num) {
  if (num < 0) {
    throw new IllegalArgumentException("Number must be positive");
  }
}

throws-Schlüsselwort

throwsDas Schlüsselwort wird in der Methodendeklaration verwendet, um die Ausnahmen anzugeben, die die Methode auslösen kann. Wenn innerhalb der Methode eine Ausnahme des angegebenen Typs ausgelöst wird, wird die Ausnahme an den Code übergeben, der die Methode aufruft, und die Ausnahme wird in diesem Code behandelt.

Zum Beispiel wird im folgenden Code, wenn innerhalb der readFile-Methode eine IOException auftritt, die Ausnahme an den Code weitergegeben, der die Methode aufruft. Im Code, der die Methode aufruft, muss die IOException abgefangen oder als behandelt deklariert werden.

Beispiel

public void readFile(String filePath) throws IOException {
  BufferedReader reader = new BufferedReader(new FileReader(filePath));
  String line = reader.readLine();
  while (line != null) {
    System.out.println(line);
    line = reader.readLine();
  }
  reader.close();
}

Eine Methode kann deklarieren, dass sie mehrere Ausnahmen wirft, getrennt durch Kommas.

Zum Beispiel deklariert die folgende Methode, dass sie RemoteException und InsufficientFundsException wirft:

import java.io.*; public class className { public void withdraw(double amount) throws RemoteException, InsufficientFundsException { // Methodenimplementierung } //Rest der Klassendefinition }

finally-Schlüsselwort

Das finally-Schlüsselwort wird verwendet, um einen Codeblock zu erstellen, der nach dem try-Codeblock ausgeführt wird.

Unabhängig davon, ob eine Ausnahme auftritt, wird der Code im finally-Block immer ausgeführt.

Im finally-Block können Sie Anweisungen wie Aufräumarbeiten und andere abschließende Operationen ausführen.

Der finally-Block erscheint nach den catch-Blöcken, und die Syntax lautet wie folgt:

try{ //Code }catch(Ausnahmetyp1Name der Ausnahmevariable1){ //Code }catch(Ausnahmetyp2Name der Ausnahmevariablen2){ //Code }finally{ //Code }

Beispiel

Code der Datei ExcepTest.java:

public class ExcepTest{ public static void main(String args[]){ int a[] = new int[2]; try{ System.out.println("Zugriff auf Element drei:" + a[3]); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Ausnahme ausgelöst :" + e); } finally{ a[0] = 6; System.out.println("Wert des ersten Elements: " +a[0]); System.out.println("Die finally-Anweisung wird ausgeführt"); } } }

Das Ergebnis des Kompilierens und Ausführens des obigen Beispiels ist wie folgt:

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed

Beachten Sie Folgendes:

  • Ein catch kann nicht unabhängig von einem try existieren.
  • Das Hinzufügen eines finally-Blocks nach try/catch ist nicht verpflichtend.
  • Nach einem try-Block darf es nicht sein, dass weder ein catch-Block noch ein finally-Block vorhanden ist.
  • Zwischen den try-, catch- und finally-Blöcken darf kein Code eingefügt werden.

try-with-resources

Nach JDK 7 führte Java eine neuetry-with-resourceSyntaxstruktur ein, die darauf abzielt, Ressourcen automatisch zu verwalten und sicherzustellen, dass Ressourcen nach der Verwendung rechtzeitig geschlossen werden, um Ressourcenlecks zu vermeiden.

try-with-resources ist ein Mechanismus zur Ausnahmebehandlung, der Ressourcen, die in einem try-Block deklariert wurden, automatisch schließt, ohne sie explizit in einem finally-Block schließen zu müssen.

In einer try-with-resources-Anweisung müssen Sie Ressourcen nur nach dem try-Schlüsselwort deklarieren, gefolgt von einem Codeblock. Unabhängig davon, ob die Operationen im Codeblock erfolgreich sind, werden die Ressourcen automatisch geschlossen, nachdem die Ausführung des try-Blocks abgeschlossen ist.

try (resource declaration) {
  // 使用的资源
} catch (ExceptionType e1) {
  // 异常块
}

In der obigen Syntax wird try verwendet, um Ressourcen zu deklarieren und zu instanziieren, und catch wird verwendet, um alle Ausnahmen zu behandeln, die beim Schließen der Ressourcen ausgelöst werden können.

Hinweis:Die try-with-resources-Anweisung schließt alle Ressourcen, die die AutoCloseable-Schnittstelle implementieren.

Beispiel

import java.io.*;

public class ExampleTest {

    public static void main(String[] args) {
    String line;
        try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
            while ((line = br.readLine()) != null) {
                System.out.println("Line =>"+line);
            }
        } catch (IOException e) {
            System.out.println("IOException in try block =>" + e.getMessage());
        }
    }
}

Die Ausgabe des obigen Beispiels ist:

IOException in try block =>test.txt (No such file or directory)

Im obigen Beispiel instanziieren wir ein BufferedReader-Objekt, um Daten aus der Datei test.txt zu lesen.

In der try-with-resources-Anweisung wird das BufferedReader-Objekt deklariert und instanziiert. Nach Abschluss der Ausführung wird die Ressource automatisch geschlossen, unabhängig davon, ob die try-Anweisung normal ausgeführt wird oder eine Ausnahme auslöst.

Wenn eine Ausnahme auftritt, können Sie catch verwenden, um die Ausnahme zu behandeln.

Betrachten wir nun, wie mantry-with-resourcesnicht verwendet und stattdessenfinallyzum Schließen von Ressourcen verwendet. Der gesamte Codeumfang ist viel größer, und er ist komplexer und umständlicher:

Beispiel

import java.io.*;

class ExampleTest {
    public static void main(String[] args) {
        BufferedReader br = null;
        String line;

        try {
            System.out.println("Betreten des try-Blocks");
            br = new BufferedReader(new FileReader("test.txt"));
            while ((line = br.readLine()) != null) {
            System.out.println("Line =>"+line);
            }
        } catch (IOException e) {
            System.out.println("IOException in try block =>" + e.getMessage());
        } finally {
            System.out.println("Betreten des finally-Blocks");
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                System.out.println("IOException im finally-Block =>"+e.getMessage());
            }
        }
    }
}

Die Ausgabe des obigen Beispiels ist:

Entering try block
IOException in try block =>test.txt (No such file or directory)
Entering finally block

try-with-resources: Umgang mit mehreren Ressourcen

In einer try-with-resources-Anweisung können mehrere Ressourcen deklariert werden, indem Semikolons;zur Trennung der Ressourcen verwendet werden:

Beispiel

import java.io.*;
import java.util.*;
class ExampleTest {
    public static void main(String[] args) throws IOException{
        try (Scanner scanner = new Scanner(new File("testRead.txt"));
            PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
            while (scanner.hasNext()) {
                writer.print(scanner.nextLine());
            }
        }
    }
}

Das obige Beispiel verwendet ein Scanner-Objekt, um eine Zeile aus der Datei testRead.txt zu lesen und sie in eine neue Datei testWrite.txt zu schreiben.

Wenn mehrere Ressourcen deklariert werden, schließt dietry-with-resources-Anweisung diese Ressourcen in umgekehrter Reihenfolge. In diesem Beispiel wird zuerst das PrintWriter-Objekt geschlossen und dann das Scanner-Objekt.

Weitere Informationen finden Sie unter:


Benutzerdefinierte Ausnahmen deklarieren

In Java können Sie benutzerdefinierte Ausnahmen definieren. Beachten Sie die folgenden Punkte, wenn Sie Ihre eigene Ausnahmeklasse schreiben.

  • Alle Ausnahmen müssen Unterklassen von Throwable sein.
  • Wenn Sie eine geprüfte Ausnahmeklasse schreiben möchten, müssen Sie von der Klasse Exception erben.
  • Wenn Sie eine Laufzeit-Ausnahmeklasse schreiben möchten, müssen Sie von der Klasse RuntimeException erben.

Sie können Ihre eigene Ausnahmeklasse wie folgt definieren:

class MyException extends Exception{ }

Eine Ausnahmeklasse, die nur durch Erben von der Klasse Exception erstellt wird, ist eine geprüfte Ausnahmeklasse.

Die folgende Klasse InsufficientFundsException ist eine benutzerdefinierte Ausnahmeklasse, die von Exception erbt.

Eine Ausnahmeklasse enthält wie jede andere Klasse Variablen und Methoden.

Beispiel

Das folgende Beispiel ist eine Simulation eines Bankkontos. Es identifiziert das Konto anhand der Bankkartennummer und unterstützt Einzahlungs- und Auszahlungsvorgänge.

Code der Datei InsufficientFundsException.java:

//Dateiname: InsufficientFundsException.java import java.io.*; //Benutzerdefinierte Ausnahmeklasse, die von der Klasse Exception erbt public class InsufficientFundsException extends Exception { //Der Betrag hier wird verwendet, um den Fehlbetrag zu speichern, wenn eine Exception auftritt (wenn der Auszahlungsbetrag den Kontostand übersteigt). private double amount; public InsufficientFundsException(double amount) { this.amount = amount; } public double getAmount() { return amount; } }

Um zu demonstrieren, wie unsere benutzerdefinierte Exception-Klasse verwendet wird,

Die unten stehende Klasse CheckingAccount enthält eine Methode withdraw(), die eine InsufficientFundsException auslöst.

Code der Datei CheckingAccount.java:

//Dateiname: CheckingAccount.java import java.io.*; //Diese Klasse simuliert ein Bankkonto public class CheckingAccount { //balance ist der Kontostand, number ist die Kartennummer private double balance; private int number; public CheckingAccount(int number) { this.number = number; } //Methode: Geld einzahlen public void deposit(double amount) { balance += amount; } //Methode: Geld abheben public void withdraw(double amount) throws InsufficientFundsException { if(amount <= balance) { balance -= amount; } else { double benötigt = amount - balance; throw new InsufficientFundsException(benötigt); } } //Methode: Kontostand zurückgeben public double getBalance() { return balance; } //Methode: Kartennummer zurückgeben public int getNumber() { return number; } }

Das folgende BankDemo-Programm zeigt, wie die Methoden deposit() und withdraw() der Klasse CheckingAccount aufgerufen werden.

Code der Datei BankDemo.java:

//Dateiname: BankDemo.java public class BankDemo { public static void main(String [] args) { CheckingAccount c = new CheckingAccount(101); System.out.println("Einzahlung von $500..."); c.deposit(500.00); try { System.out.println("\nAbhebung von $100..."); c.withdraw(100.00); System.out.println("\nAbhebung von $600..."); c.withdraw(600.00); }catch(InsufficientFundsException e) { System.out.println("Entschuldigung, aber es fehlen Ihnen $" + e.getAmount()); e.printStackTrace(); } } }

Kompilieren Sie die oben genannten drei Dateien und führen Sie das BankDemo-Programm aus. Das Ergebnis wird unten angezeigt:

Depositing $500...

Withdrawing $100...

Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
        at CheckingAccount.withdraw(CheckingAccount.java:25)
        at BankDemo.main(BankDemo.java:13)

Allgemeine Ausnahmen

Java definiert zwei Arten von Ausnahmen und Fehlern.

  • JVM (JavaVirtual Machine))-Ausnahmen:Von der JVM ausgelöste Ausnahmen oder Fehler. Zum Beispiel: Klasse NullPointerException, Klasse ArrayIndexOutOfBoundsException, Klasse ClassCastException.
  • Ausnahmen auf Programmebene:Von Programmen oder API-Programmen ausgelöste Ausnahmen. Zum Beispiel: Klasse IllegalArgumentException, Klasse IllegalStateException.

Best Practices für die Ausnahmebehandlung

  • Fangen Sie Ausnahmen an geeigneten Stellen ab und behandeln Sie sie ordnungsgemäß, um die Stabilität und Zuverlässigkeit des Programms zu gewährleisten.
  • Vermeiden Sie übermäßiges Abfangen von Ausnahmen; versuchen Sie, gezielt bestimmte Ausnahmetypen abzufangen.
  • Verwenden Sie finally-Blöcke, um Ressourcen freizugeben, z. B. durch Schließen von Dateien oder Datenbankverbindungen, um sicherzustellen, dass Ressourcen ordnungsgemäß freigegeben werden.
  • Priorisieren Sie die Behandlung überprüfter Ausnahmen und vermeiden Sie, überprüfte Ausnahmen in ungeprüfte Ausnahmen umzuwandeln.

Die Ausnahmebehandlung ist ein wichtiger Bestandteil beim Schreiben robuster Java-Anwendungen. Eine ordnungsgemäße Behandlung von Ausnahmen kann die Wartbarkeit und Zuverlässigkeit von Programmen verbessern.

Weitere Erweiterungen