Ausnahmearten - 1

„Ich wollte heute noch über eine Sache reden. In Java werden alle Ausnahmen in zwei Arten unterteilt: geprüft und ungeprüft (diejenigen, die abgefangen werden müssen und diejenigen, die nicht abgefangen werden müssen). Standardmäßig müssen alle Ausnahmen abgefangen werden.“

„Kann man absichtlich Ausnahmen im Code auslösen?“

„Man kann jede beliebige Ausnahme im eigenen Code auslösen. Du kannst sogar deine eigenen Ausnahmen schreiben. Darüber erfährst du später mehr. Für den Moment konzentrieren wir uns auf Ausnahmen, die von der Java-Maschine ausgelöst werden.“

„Okay.“

„Wenn ClassNotFoundException oder FileNotFoundException in einer Methode ausgelöst werden (auftreten), muss der Entwickler diese in der Methodendeklaration angeben. Das sind geprüfte Ausnahmen. Das sieht dann normalerweise so aus:“

Beispiele für geprüfte Ausnahmen
public static void method1() throws ClassNotFoundException, FileNotFoundException

public static void main() throws IOException
public static void main() // Doesn't throw any exceptions

„Also schreiben wir einfach ‚throws‘, gefolgt von einer durch Kommas getrennten Liste von Ausnahmen, richtig?“

„Ja. Das ist aber noch nicht alles. Damit das Programm kompiliert wird, muss die Methode, die im Beispiel unten method1 aufruft, eine von zwei Aktionen ausführen: entweder diese Ausnahmen abfangen oder sie (an den Aufrufer) zurückwerfen und die neu ausgelösten Ausnahmen in ihrer Deklaration angeben. "

„Nochmal. Wenn deine main-Methode eine Methode aufrufen muss, deren Deklaration ‚throws FileNotFoundException, …‘ enthält, dann musst du eines von zwei Dingen tun:

1) FileNotFoundException, … abfangen

Du musst den Code, der die unsichere Methode aufruft, in einen try-catch-Block einschließen.

2) FileNotFoundException, … nicht abfangen

Du musst diese Ausnahmen zur throws-Liste deiner main-Methode hinzufügen.“

„Kannst du mir dafür ein Beispiel geben?“

„Sieh dir das an:

Beispiele für geprüfte Ausnahmen
public static void main(String[] args)
{
    method1();
}

public static void method1() throws FileNotFoundException, ClassNotFoundException
{
    //Throws FileNotFoundException if the file doesn't exist
    FileInputStream fis = new FileInputStream("C2:\badFileName.txt");
}

„Der Code in diesem Beispiel wird nicht kompiliert, da die main-Methode methode1() aufruft, die Ausnahmen auslöst, die abgefangen werden müssen.“

„Damit der Code kompiliert werden kann, müssen wir der main-Methode die Ausnahmebehandlung hinzufügen. Dazu hast du zwei verschiedene Möglichkeiten:“

Option 1: Wir lösen die Ausnahme einfach erneut aus (an den Aufrufer):
public static void main(String[] args)  throws FileNotFoundException, ClassNotFoundException 
{
    method1();
}

public static void method1() throws FileNotFoundException, ClassNotFoundException
{
    //Throws FileNotFoundException if the file doesn't exist
    FileInputStream fis = new FileInputStream("C2:\badFileName.txt");
}

„Und hier fangen wir sie mit einem try-catch ab:“

Option 2: Ausnahme abfangen:
public static void main(String[] args)
{
    try
    {
        method1();
    }
    catch(Exception e)
    {
    }
}

public static void method1() throws FileNotFoundException, ClassNotFoundException
{
    //Throws FileNotFoundException if the file doesn't exist
    FileInputStream fis = new FileInputStream("C2:\badFileName.txt");
}

„Langsam verstehe ich.“

„Sieh dir das folgende Beispiel an. Es wird dir helfen, den Rest zu verstehen.“

Anstatt Ausnahmen zu behandeln, lösen wir sie für Methoden weiter unten im Stack erneut aus, die wissen, wie man sie behandelt:
public static void method2() throws FileNotFoundException, ClassNotFoundException
{
    method1();
}
Eine Ausnahme behandeln und eine andere auslösen:
public static void method3() throws ClassNotFoundException
{
   try
    {
        method1();
    }
    catch (FileNotFoundException e)
    {
        System.out.println("FileNotFoundException has been caught.");
    }
}
Beide Ausnahmen abfangen, keine auslösen:
public static void method4()
{
    try
    {
        method1();
    }
    catch (FileNotFoundException e)
    {
        System.out.println("FileNotFoundException has been caught.");
    }
    catch (ClassNotFoundException e)
    {
        System.out.println("ClassNotFoundException has been caught.");
    }
}

„Es gibt noch eine weitere Art von Ausnahme, die RuntimeException, und Klassen, die von ihr erben. Die musst du nicht abfangen. Dies sind ungeprüfte Ausnahmen. Sie gelten als schwer vorhersehbar. Du kannst mit ihnen auf die gleiche Weise umgehen, aber du musst sie nicht in einer throws-Anweisung angeben.“