Was ist Ausnahmebehandlung?
- Reagieren Sie auf Fehler, die beim Ausführen der App auftreten
- Ausnahme im engeren Sinne: Ein Fehler, der nicht in der Verantwortung des Entwicklers ausgeschlossen werden kann
- Die Datei existiert nicht
- Die Verbindungsziel-DB wurde gestoppt
- Java muss diese Fehler behandeln
- ** Die Ausnahme ist Typ (Klasse) **
- ** Darstellen als Klassenhierarchie mit allgemeinen Ausnahmen als obere Klassen und Ausnahmen in Einzelsituationen als untere Klassen **
versuchen Sie ... die Syntax zu fangen
- ** try block **: Originalverarbeitung
- ** catch block **: Wird vom Ausnahmetyp aufgerufen
- Ausnahme ausgelöst = ** Ausnahme ausgelöst **
- Zugriff auf das Ausnahmeobjekt über die angegebene ** Ausnahmevariable (e oder ex) **
- Da der Bereich in Blockeinheiten festgelegt ist, ist derselbe Variablenname (e) auch dann in Ordnung, wenn mehrere Catch-Blöcke vorhanden sind.
- Ausnahmeklassenmethode
- ** getMessage () **: Fehlermeldung abrufen
- ** getLocalizedMessage () **: Lokalisierte Fehlermeldung abrufen
- ** getCause () **: Liefert die Fehlerursache
- ** getStackTrace () **: Stack-Trace abrufen
- ** printStackTrace () **: Stack-Trace-Ausgabe
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TryBasic {
public static void main(String[] args) {
try {
var in = new FileInputStream("C:/data/nothing.gif");
var data = -1;
while ((data = in.read()) != -1) {
System.out.printf("%02X ", data);
}
//Lösen Sie eine FileNotFoundException-Ausnahme in der FileInputStream-Klasse aus
} catch (FileNotFoundException e) {
System.out.println("Die Datei wurde nicht gefunden.");
} catch (IOException e) {
//Greifen Sie über die angegebene Ausnahmevariable (e) auf das Ausnahmeobjekt zu.
e.printStackTrace();
}
}
}
Stapelspur
- ** Methodenverlauf vor Auftreten der Ausnahme **
- Aufzeichnen in der Reihenfolge der Aufrufe ausgehend von der Hauptmethode, die der Einstiegspunkt ist.
- Überprüfen Sie, ob eine unbeabsichtigte Methode aufgerufen wird und ob der Prozess falsch ist
endlich blockieren
- Der letzte Block, der mit oder ohne Ausnahmen ausgeführt werden soll
- Verarbeitung von Ressourcen, die im Try-Block usw. verwendet werden.
- Endlich nur ein Block
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TryFinally {
public static void main(String[] args) {
FileInputStream in = null;
try {
in = new FileInputStream("C:/data/nothing.gif");
var data = -1;
while ((data = in.read()) != -1) {
System.out.printf("%02X ", data);
}
} catch (FileNotFoundException e) {
System.out.println("Die Datei wurde nicht gefunden.");
} catch (IOException e) {
e.printStackTrace();
} finally {
//Datei schließen mit oder ohne Ausnahme
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Try-with-Resource-Syntax
- Empfohlen, weil es einfacher ist als zu versuchen ... endlich Syntax
- ** Wirklich unnötig, da Ressourcen automatisch freigegeben werden, wenn der try-Block beendet wird! ** ** **
- Hinweis:
- ** Implementieren Sie die AutoCloseable-Schnittstelle **
* Reader/Writer/InputStream/OutputStream/Connection/Statement/ResultSet
- ** Änderungen der Reihenfolge der Ressourcenfreigabe **
- Bei der herkömmlichen Syntax try ... finally war die Ressource zum Zeitpunkt des Catch-Blocks aktiv
- Beim Versuch mit Ressource wird die Ressource freigegeben, wenn der Versuchsblock beendet wird.
- ** Unterschiedlicher Ressourcenumfang **
- Die try ... -Syntax verarbeitet Ressourcen blockübergreifend, sodass Ressourcenvariablen außerhalb des try-Blocks deklariert werden.
- In try-with-resource ist der Bereich auf unter dem try-Block beschränkt (in Java 9 oder höher können Ressourcen angegeben werden, die außerhalb des try-Blocks deklariert wurden).
*
var input = new FileInputStream(...)
* try(input){...}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TryWithResources {
//Ressourcendeklaration am Anfang des Blocks
public static void main(String[] args) {
try (var in = new FileInputStream("C:/data/hogee.gif")) {
var data = -1;
while ((data = in.read()) != -1) {
System.out.printf("%02X ", data);
}
//Automatische Ressourcenfreigabe beim Beenden des Try-Blocks
} catch (FileNotFoundException e) {
System.out.println("Datei nicht gefunden.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hierarchische Struktur von Ausnahmeklassen
- Aus Sicht der Klassenhierarchie gehören alle Ausnahme- / Fehlerklassen zu einem Hierarchiebaum mit ** Throwable-Klasse ** als Apex.
- ** Fehlerklasse **: Schwerwiegender Fehler ---- ** [Keine Ausnahmebehandlung] **
- Untergeordnete Fehler sind ** Fehlerausnahmen **
- IOErrer: Schwerer E / A-Fehler, VirtualMachineError: Fehler auf Ebene der virtuellen Maschine
- ** Ausnahmeklasse ** ‥ ‥ ‥ ‥ ‥ ‥ ‥ ‥ ‥ ‥ ‥ ‥
- ** RuntimeException-Klasse ** ---- ** [Ausnahmebehandlung optional] **
- Untergeordnete Fehler sind ** ungeprüfte Ausnahmen ** (= Laufzeitausnahmen)
- IllegalArgumentException: Unzulässiges Argument, NullPointerException: Objekt ist null
- Andere untergeordnete Fehler sind ** Inspektionsausnahmen **
- FileNotFoundException: Datei existiert nicht, SQLException: Problem beim Zugriff auf DB
Hinweise zur Ausnahmebehandlung
- ** Nicht mit Ausnahme fangen **
catch (Ausnahme e)
fängt alle Ausnahmen ab
- IOException Spezifischere FileNotFoundException
- ** Multi-Catch verwenden **
- Machen Sie dasselbe für mehrere Ausnahmen
Ausnahme 1 | Ausnahme 2
(in beiden Fällen)
- ** Blockreihenfolge fangen **
- Wenn mehrere vorhanden sind, hat die Erstbeschreibung Vorrang
- ** Schreibe zuerst niedrigere Ausnahmen, später höhere Ausnahmen **
//Mehrfachfang
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class TryMulti {
public static void main(String[] args) {
try {
var in = new FileInputStream("C:/data/nasi.gif");
var data = -1;
while ((data = in.read()) != -1) {
System.out.printf("%02X ", data);
}
var uri = new URI( "https://www.neko.example.com");
System.out.println(uri.toString());
//Mehrfachfang
} catch (IOException | URISyntaxException e) {
System.out.println("Zugriff auf die Datei nicht möglich.");
e.printStackTrace();
}
}
}
Eine Ausnahme auslösen
- Zusätzlich zum Werfen von Standardbibliotheken ** Entwickler können werfen **
- Sie können jedes Ausnahmeobjekt mit "Ausnahmeobjekt auslösen" übergeben.
- ** Deklarieren Sie Ausnahmen, die in der Throws-Klausel ausgelöst werden dürfen **
- throw: Wirft eine Ausnahme aus
- löst aus: In Methode / Konstruktor deklariert
public FileInputStream(File file) throws FileNotFoundException{
//Abkürzung
Ausnahme werfen Aufmerksamkeit
- ** Keine Ausnahme werfen **
- ** Aktivierte / deaktivierte Ausnahmen richtig auswählen **
- Verwenden Sie ** Standardausnahmen ** so oft wie möglich
- ** NullPointerException **: Objekt ist null
- ** IndexOutOfBoundsException **: Der Array-Index liegt außerhalb des Bereichs
- ** UnsupportedOperationException **: Der Anforderungsvorgang wird nicht unterstützt
- ** IllegalArgumentException **: Problem mit dem an die Methode übergebenen Argument
- ** IllegalStateException **: Methode, die aufgerufen wird, wenn sie nicht im beabsichtigten Zustand ist
- ** ArithmeticException **: Bei der Berechnung tritt eine Ausnahmebedingung auf
- ** NumberFormatException **: Falsches Zahlenformat
- Private Methode verwendet ** Assert-Anweisung **
- AssertionError-Ausnahme, wenn der bedingte Ausdruck falsch ist
- Funktioniert nur, wenn die Option
-ea
im Java-Befehl angegeben ist
public class AssertBasic {
private static double getTrapezoidArea(double upper, double lower, double height) {
//Eine Ausnahme tritt auf, wenn das Argument 0 oder weniger ist
assert upper > 0 && lower > 0 && height > 0;
return (upper + lower) * height / 2;
}
public static void main(String[] args) {
System.out.println(AssertBasic.getTrapezoidArea(-2, 4, 0));
}
}
Ausnahme neu werfen
- Nicht vor Ort bearbeiten ** Überlassen Sie den Vorgang dem Anrufer **
- Grundsätzlich sollte anstelle der individuellen Verarbeitung vor Ort die individuelle Verarbeitung aufgerufen und der Ablauf der Anwendung selbst gesteuert werden. ** sollte durch übergeordneten Code verarbeitet werden. **
- Der Ausnahmetyp kann mit Bedacht beurteilt werden (Java7 ~).
- Nur der Ausnahmetyp kann mit Würfen deklariert werden
- Keine Notwendigkeit für Multi-Catch
public class TryRethrow {
//MySampleException,Die Rethrow-Methode kann in MyLibException auftreten
public static void rethrow(boolean flag) throws MySampleException, MyLibException {
try {
if (flag) {
throw new MySampleException();
} else {
throw new MyLibException();
}
//Empfangen Sie mit Ausnahmetyp und werfen Sie erneut, wie es ist
} catch (Exception e) {
throw e;
}
}
}
Übersetzungsausnahme
- ** Sammle einzelne Ausnahmen einmal, bündle sie als Ausnahmen für übergeordnete Apps und wirf sie erneut **
- Ausnahmen können in app-spezifische Ausnahmen gruppiert werden
- Der Anrufer sollte keine einzelnen Ausnahmen kennen, ** sollte Ausnahmen höherer Ebenen kennen **
- Um die ursprüngliche Ursache aus der übersetzten obersten Ausnahme zu erhalten **
getCause
Methode **
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Paths;
//Sie müssen MySampleException nur als Übersetzungsausnahme kennen
public class UseTrans {
public void readHttpPages() throws MySampleException {
try (var reader = Files.newBufferedReader(Paths.get("C:/data/link.txt"))) {
var line = "";
while ((line = reader.readLine()) != null) {
var client = HttpClient.newHttpClient();
var req = HttpRequest.newBuilder().uri(URI.create(line)).build();
var res = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body());
}
} catch (IOException | InterruptedException e) {
throw new MySampleException(e);
}
}
}
Proprietäre Ausnahmeklasse
- Ausnahmeklassen können in der App definiert werden
- ** Ausnahme erben (abgeleitete Klasse) **
- ** Überschreiben des Konstruktors **
- Definieren Sie den durch Exception definierten Konstruktor neu und rufen Sie super OK auf
- Ausnahmen mit eindeutigen Feld- und Methodenimplementierungen sind möglich
//Ausnahme erben (abgeleitete Klasse)
public class MySampleException extends Exception {
//Konstruktor überschreiben
public MySampleException() {
super();
}
public MySampleException(String message) {
super(message);
}
public MySampleException(String message, Throwable cause) {
super(message, cause);
}
public MySampleException(Throwable cause) {
super(cause);
}
}