Java - Ausnahmen
Eine Ausnahme (oder ein außergewöhnliches Ereignis) ist ein Problem, das während der Ausführung eines Programms auftritt. Wenn eine Ausnahme auftritt, wird der normale Ablauf des Programms unterbrochen und das Programm/die Anwendung wird abnormal beendet, was nicht empfohlen wird, daher müssen diese Ausnahmen behandelt werden.
Eine Ausnahme kann aus vielen verschiedenen Gründen auftreten. Im Folgenden sind einige Szenarien aufgeführt, in denen eine Ausnahme auftritt.
-
Ein Benutzer hat ungültige Daten eingegeben.
-
Eine zu öffnende Datei kann nicht gefunden werden.
-
Eine Netzwerkverbindung wurde mitten in der Kommunikation unterbrochen oder die JVM hat keinen Arbeitsspeicher mehr.
Einige dieser Ausnahmen werden durch Benutzerfehler verursacht, andere durch Programmierfehler und wieder andere durch physische Ressourcen, die auf irgendeine Weise ausgefallen sind.
Basierend auf diesen haben wir drei Kategorien von Ausnahmen. Sie müssen sie verstehen, um zu wissen, wie die Ausnahmebehandlung in Java funktioniert.
-
Überprüfte Ausnahmen − Eine geprüfte Ausnahme ist eine Ausnahme, die vom Compiler zur Kompilierzeit geprüft (benachrichtigt) wird, diese Ausnahmen werden auch als Kompilierzeit-Ausnahmen bezeichnet. Diese Ausnahmen können nicht einfach ignoriert werden, der Programmierer sollte sich um diese Ausnahmen kümmern (behandeln).
Zum Beispiel, wenn Sie FileReader verwenden Klasse in Ihrem Programm, um Daten aus einer Datei zu lesen, wenn die in ihrem Konstruktor angegebene Datei nicht existiert, dann eine FileNotFoundException auftritt, und der Compiler fordert den Programmierer auf, die Ausnahme zu behandeln.
Beispiel
Live-Demoimport java.io.File; import java.io.FileReader; public class FilenotFound_Demo { public static void main(String args[]) { File file = new File("E://file.txt"); FileReader fr = new FileReader(file); } }
Wenn Sie versuchen, das obige Programm zu kompilieren, erhalten Sie die folgenden Ausnahmen.
Ausgabe
C:\>javac FilenotFound_Demo.java FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown FileReader fr = new FileReader(file); ^ 1 error
Hinweis − Da die Methoden read() und Schließen() der FileReader-Klasse IOException auslöst, können Sie beobachten, dass der Compiler zusammen mit FileNotFoundException benachrichtigt, IOException zu behandeln.
-
Ungeprüfte Ausnahmen − Eine ungeprüfte Ausnahme ist eine Ausnahme, die zum Zeitpunkt der Ausführung auftritt. Diese werden auch als Laufzeitausnahmen bezeichnet . Dazu gehören Programmierfehler wie Logikfehler oder die unsachgemäße Verwendung einer API. Laufzeitausnahmen werden zum Zeitpunkt der Kompilierung ignoriert.
Zum Beispiel, wenn Sie in Ihrem Programm ein Array der Größe 5 deklariert haben und versuchen, das 6 te aufzurufen Element des Arrays dann eine ArrayIndexOutOfBoundsExceptionException auftritt.
Beispiel
Live-Demopublic class Unchecked_Demo { public static void main(String args[]) { int num[] = {1, 2, 3, 4}; System.out.println(num[5]); } }
Wenn Sie das obige Programm kompilieren und ausführen, erhalten Sie die folgende Ausnahme.
Ausgabe
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)
-
Fehler − Dies sind keine Ausnahmen, sondern Probleme, die außerhalb der Kontrolle des Benutzers oder des Programmierers auftreten. Fehler werden normalerweise in Ihrem Code ignoriert, da Sie selten etwas gegen einen Fehler unternehmen können. Wenn beispielsweise ein Stapelüberlauf auftritt, tritt ein Fehler auf. Sie werden auch beim Kompilieren ignoriert.
Ausnahmehierarchie
Alle Ausnahmeklassen sind Untertypen der java.lang.Exception-Klasse. Die Ausnahmeklasse ist eine Unterklasse der Throwable-Klasse. Neben der Ausnahmeklasse gibt es eine weitere Unterklasse namens Error, die von der Throwable-Klasse abgeleitet ist.
Fehler sind anormale Zustände, die bei schwerwiegenden Fehlern auftreten, diese werden von den Java-Programmen nicht behandelt. Fehler werden generiert, um auf Fehler hinzuweisen, die von der Laufzeitumgebung generiert wurden. Beispiel:JVM hat keinen Arbeitsspeicher mehr. Normalerweise können Programme Fehler nicht beheben.
Die Exception-Klasse hat zwei Hauptunterklassen:die IOException-Klasse und die RuntimeException-Klasse.

Im Folgenden finden Sie eine Liste der häufigsten aktivierten und nicht aktivierten Java-integrierten Ausnahmen.
Ausnahmemethoden
Es folgt die Liste wichtiger Methoden, die in der Throwable-Klasse verfügbar sind.
Sr.No. | Methode &Beschreibung |
---|---|
1 | öffentlicher String getMessage() Gibt eine detaillierte Meldung über die aufgetretene Ausnahme zurück. Diese Nachricht wird im Throwable-Konstruktor initialisiert. |
2 | Public Throwable getCause() Gibt die Ursache der Ausnahme zurück, wie sie durch ein Throwable-Objekt dargestellt wird. |
3 | öffentlicher String toString() Gibt den Namen der Klasse verkettet mit dem Ergebnis von getMessage() zurück. |
4 | public void printStackTrace() Gibt das Ergebnis von toString() zusammen mit dem Stack-Trace an System.err aus, den Fehlerausgabestrom. |
5 | öffentliches StackTraceElement [] getStackTrace() Gibt ein Array zurück, das jedes Element im Stack-Trace enthält. Das Element bei Index 0 stellt den Anfang des Aufrufstapels dar, und das letzte Element im Array stellt die Methode am Ende des Aufrufstapels dar. |
6 | Public Throwable fillInStackTrace() Füllt den Stack-Trace dieses Throwable-Objekts mit dem aktuellen Stack-Trace und ergänzt alle vorherigen Informationen im Stack-Trace. |
Abfangen von Ausnahmen
Eine Methode fängt eine Ausnahme mit einer Kombination aus try ab und fangen Schlüsselwörter. Ein Try/Catch-Block wird um den Code platziert, der möglicherweise eine Ausnahme generiert. Code innerhalb eines try/catch-Blocks wird als geschützter Code bezeichnet, und die Syntax für die Verwendung von try/catch sieht wie folgt aus −
Syntax
try { // Protected code } catch (ExceptionName e1) { // Catch block }
Der für Ausnahmen anfällige Code wird in den try-Block gestellt. Wenn eine Ausnahme auftritt, wird diese aufgetretene Ausnahme von dem ihr zugeordneten catch-Block behandelt. Jedem try-Block sollte unmittelbar entweder ein catch-Block oder ein finally-Block folgen.
Eine catch-Anweisung beinhaltet das Deklarieren der Art der Ausnahme, die Sie abfangen möchten. Wenn in geschütztem Code eine Ausnahme auftritt, wird der Catch-Block (oder die Catch-Blöcke) nach dem Try überprüft. Wenn der Typ der aufgetretenen Ausnahme in einem Catch-Block aufgeführt ist, wird die Ausnahme an den Catch-Block übergeben, ähnlich wie ein Argument an einen Methodenparameter übergeben wird.
Beispiel
Das Folgende ist ein Array, das mit 2 Elementen deklariert ist. Dann versucht der Code, auf die 3 rd zuzugreifen Element des Arrays, das eine Ausnahme auslöst.
Live-Demo// File Name : ExcepTest.java import java.io.*; public class ExcepTest { public static void main(String args[]) { try { int a[] = new int[2]; System.out.println("Access element three :" + a[3]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Exception thrown :" + e); } System.out.println("Out of the block"); } }
Dies wird das folgende Ergebnis erzeugen −
Ausgabe
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3 Out of the block
Mehrere Catch-Blöcke
Auf einen try-Block können mehrere catch-Blöcke folgen. Die Syntax für mehrere Catch-Blöcke sieht wie folgt aus −
Syntax
try { // Protected code } catch (ExceptionType1 e1) { // Catch block } catch (ExceptionType2 e2) { // Catch block } catch (ExceptionType3 e3) { // Catch block }
Die vorherigen Anweisungen demonstrieren drei catch-Blöcke, aber Sie können nach einem einzigen Versuch beliebig viele davon haben. Wenn im geschützten Code eine Ausnahme auftritt, wird die Ausnahme an den ersten Catch-Block in der Liste geworfen. Wenn der Datentyp der ausgelösten Ausnahme mit ExceptionType1 übereinstimmt, wird sie dort abgefangen. Wenn nicht, wird die Ausnahme an die zweite catch-Anweisung weitergegeben. Dies wird fortgesetzt, bis die Ausnahme entweder abgefangen wird oder alle Fangvorgänge durchläuft. In diesem Fall stoppt die aktuelle Methode die Ausführung und die Ausnahme wird an die vorherige Methode in der Aufrufliste geworfen.
Beispiel
Hier ist ein Codesegment, das zeigt, wie mehrere try/catch-Anweisungen verwendet werden.
try { file = new FileInputStream(fileName); x = (byte) file.read(); } catch (IOException i) { i.printStackTrace(); return -1; } catch (FileNotFoundException f) // Not valid! { f.printStackTrace(); return -1; }
Mehrere Arten von Ausnahmen abfangen
Seit Java 7 können Sie mehr als eine Ausnahme mit einem einzigen Catch-Block behandeln, diese Funktion vereinfacht den Code. So würden Sie es machen −
catch (IOException|FileNotFoundException ex) { logger.log(ex); throw ex;
Die Throws/Throw-Keywords
Wenn eine Methode eine geprüfte Ausnahme nicht behandelt, muss die Methode dies mithilfe der throws deklarieren Stichwort. Das throws-Schlüsselwort erscheint am Ende der Signatur einer Methode.
Sie können eine Ausnahme auslösen, entweder eine neu instanziierte oder eine gerade abgefangene Ausnahme, indem Sie throw verwenden Schlüsselwort.
Versuchen Sie, den Unterschied zwischen Throws und Throw-Keywords, Throws, zu verstehen wird verwendet, um die Behandlung einer geprüften Ausnahme zu verschieben und throw wird verwendet, um explizit eine Ausnahme aufzurufen.
Die folgende Methode deklariert, dass sie eine RemoteException auslöst −
Beispiel
import java.io.*; public class className { public void deposit(double amount) throws RemoteException { // Method implementation throw new RemoteException(); } // Remainder of class definition }
Eine Methode kann deklarieren, dass sie mehr als eine Ausnahme auslöst. In diesem Fall werden die Ausnahmen in einer durch Kommas getrennten Liste deklariert. Beispielsweise deklariert die folgende Methode, dass sie eine RemoteException und eine InsufficientFundsException auslöst −
Beispiel
import java.io.*; public class className { public void withdraw(double amount) throws RemoteException, InsufficientFundsException { // Method implementation } // Remainder of class definition }
Der endgültige Block
Der finally-Block folgt auf einen try-Block oder einen catch-Block. Ein finally-Codeblock wird immer ausgeführt, unabhängig vom Auftreten einer Ausnahme.
Die Verwendung eines finally-Blocks ermöglicht es Ihnen, alle Bereinigungsanweisungen auszuführen, die Sie ausführen möchten, unabhängig davon, was im geschützten Code passiert.
Ein finally-Block erscheint am Ende der catch-Blöcke und hat die folgende Syntax −
Syntax
try { // Protected code } catch (ExceptionType1 e1) { // Catch block } catch (ExceptionType2 e2) { // Catch block } catch (ExceptionType3 e3) { // Catch block }finally { // The finally block always executes. }
Beispiel
Live-Demopublic class ExcepTest { public static void main(String args[]) { int a[] = new int[2]; try { System.out.println("Access element three :" + a[3]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Exception thrown :" + e); }finally { a[0] = 6; System.out.println("First element value: " + a[0]); System.out.println("The finally statement is executed"); } } }
Dies wird das folgende Ergebnis erzeugen −
Ausgabe
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3 First element value: 6 The finally statement is executed
Beachten Sie Folgendes:−
-
Eine catch-Klausel kann nicht ohne eine try-Anweisung existieren.
-
Es ist nicht zwingend, Final-Klauseln zu haben, wenn ein Try/Catch-Block vorhanden ist.
-
Der try-Block darf nicht ohne die catch-Klausel oder die finally-Klausel vorhanden sein.
-
Zwischen den try-, catch- und finally-Blöcken darf kein Code vorhanden sein.
Der Versuch mit Ressourcen
Wenn wir Ressourcen wie Streams, Verbindungen usw. verwenden, müssen wir sie im Allgemeinen explizit mit dem Endgültigen Block schließen. Im folgenden Programm lesen wir mit FileReader Daten aus einer Datei und wir schließen es mit finally block.
Beispiel
import java.io.File; import java.io.FileReader; import java.io.IOException; public class ReadData_Demo { public static void main(String args[]) { FileReader fr = null; try { File file = new File("file.txt"); fr = new FileReader(file); char [] a = new char[50]; fr.read(a); // reads the content to the array for(char c : a) System.out.print(c); // prints the characters one by one } catch (IOException e) { e.printStackTrace(); }finally { try { fr.close(); } catch (IOException ex) { ex.printStackTrace(); } } } }
versuchen Sie es mit Ressourcen , auch als automatische Ressourcenverwaltung bezeichnet , ist ein neuer Ausnahmebehandlungsmechanismus, der in Java 7 eingeführt wurde und automatisch die innerhalb des try-catch-Blocks verwendeten Ressourcen schließt.
Um diese Anweisung zu verwenden, müssen Sie lediglich die erforderlichen Ressourcen innerhalb der Klammern deklarieren, und die erstellte Ressource wird am Ende des Blocks automatisch geschlossen. Es folgt die Syntax der try-with-resources-Anweisung.
Syntax
try(FileReader fr = new FileReader("file path")) { // use the resource } catch () { // body of catch } }
Es folgt das Programm, das die Daten in einer Datei mit der try-with-resources-Anweisung liest.
Beispiel
import java.io.FileReader; import java.io.IOException; public class Try_withDemo { public static void main(String args[]) { try(FileReader fr = new FileReader("E://file.txt")) { char [] a = new char[50]; fr.read(a); // reads the contentto the array for(char c : a) System.out.print(c); // prints the characters one by one } catch (IOException e) { e.printStackTrace(); } } }
Folgende Punkte sind bei der Arbeit mit der try-with-resources-Anweisung zu beachten.
-
Um eine Klasse mit einer try-with-resources-Anweisung zu verwenden, sollte sie AutoCloseable implementieren Schnittstelle und close() Methode davon wird automatisch zur Laufzeit aufgerufen.
-
Sie können mehr als eine Klasse in der try-with-resources-Anweisung deklarieren.
-
Während Sie mehrere Klassen im try-Block der try-with-resources-Anweisung deklarieren, werden diese Klassen in umgekehrter Reihenfolge geschlossen.
-
Außer der Deklaration von Ressourcen innerhalb der Klammern ist alles dasselbe wie beim normalen try/catch-Block eines try-Blocks.
-
Die in try deklarierte Ressource wird unmittelbar vor dem Start des try-Blocks instanziiert.
-
Die im try-Block deklarierte Ressource wird implizit als final deklariert.
Benutzerdefinierte Ausnahmen
Sie können Ihre eigenen Ausnahmen in Java erstellen. Beachten Sie die folgenden Punkte, wenn Sie Ihre eigenen Ausnahmeklassen schreiben −
-
Alle Ausnahmen müssen untergeordnete Elemente von Throwable sein.
-
Wenn Sie eine geprüfte Ausnahme schreiben möchten, die automatisch durch die Handle- oder Declare-Regel erzwungen wird, müssen Sie die Exception-Klasse erweitern.
-
Wenn Sie eine Laufzeitausnahme schreiben möchten, müssen Sie die RuntimeException-Klasse erweitern.
Wir können unsere eigene Exception-Klasse wie folgt definieren −
class MyException extends Exception { }
Sie müssen nur die vordefinierte Ausnahme erweitern Klasse, um Ihre eigene Ausnahme zu erstellen. Diese gelten als geprüfte Ausnahmen. Die folgende InsufficientFundsException Klasse ist eine benutzerdefinierte Ausnahme, die die Klasse Exception erweitert und sie zu einer geprüften Ausnahme macht. Eine Ausnahmeklasse ist wie jede andere Klasse und enthält nützliche Felder und Methoden.
Beispiel
// File Name InsufficientFundsException.java import java.io.*; public class InsufficientFundsException extends Exception { private double amount; public InsufficientFundsException(double amount) { this.amount = amount; } public double getAmount() { return amount; } }
Um die Verwendung unserer benutzerdefinierten Ausnahme zu demonstrieren, enthält die folgende CheckingAccount-Klasse eine pull()-Methode, die eine InsufficientFundsException auslöst.
// File Name CheckingAccount.java import java.io.*; public class CheckingAccount { private double balance; private int number; public CheckingAccount(int number) { this.number = number; } public void deposit(double amount) { balance += amount; } public void withdraw(double amount) throws InsufficientFundsException { if(amount <= balance) { balance -= amount; }else { double needs = amount - balance; throw new InsufficientFundsException(needs); } } public double getBalance() { return balance; } public int getNumber() { return number; } }
Das folgende BankDemo-Programm demonstriert das Aufrufen der deposit()- unddraw()-Methoden von CheckingAccount.
// File Name BankDemo.java public class BankDemo { public static void main(String [] args) { CheckingAccount c = new CheckingAccount(101); System.out.println("Depositing $500..."); c.deposit(500.00); try { System.out.println("\nWithdrawing $100..."); c.withdraw(100.00); System.out.println("\nWithdrawing $600..."); c.withdraw(600.00); } catch (InsufficientFundsException e) { System.out.println("Sorry, but you are short $" + e.getAmount()); e.printStackTrace(); } } }
Kompilieren Sie alle oben genannten drei Dateien und führen Sie BankDemo aus. Dies wird das folgende Ergebnis erzeugen −
Ausgabe
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)
Häufige Ausnahmen
In Java ist es möglich, zwei Kategorien von Ausnahmen und Fehlern zu definieren.
-
JVM-Ausnahmen − Dies sind Ausnahmen/Fehler, die ausschließlich oder logisch von der JVM geworfen werden. Beispiele:NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException.
-
Programmatische Ausnahmen − Diese Ausnahmen werden explizit von der Anwendung oder den API-Programmierern ausgelöst. Beispiele:IllegalArgumentException, IllegalStateException.
Java