Kurzeinstieg Java: Ausnahmen

Was sind Ausnahmen?

Bearbeiten

Ausnahmen sind Unterbrechungen vom normalen, geplanten Programmfluss. In der Regel entstehen sie durch Fehler, die der Anwender oder der Programmierer gemacht hat. Auf Ausnahmen kann man reagieren, alternativ bricht das Programm in der Regel ab. Java stellt Sprachelemente bereit, mit denen Ausnahmen abgefangen und erzeugt werden können. Ferner sind Ausnahmen in der Umgebung von Java kategorisiert.

Grundstruktur der Ausnahmebehandlung

Bearbeiten

Es wird ein Block, der unter Umständen eine Ausnahme auslösen könnte mit try { … } eingeschlossen. Anschließend folgt catch(AusnahmeTyp x) { … }. Hier wird die eigentliche Ausnahme aufgefangen. Es ist möglich, mehrere Ausnahmen in einem catch-Block unterzubringen. Ist die spezielle Ausnahme im catch-Parameter nicht aufgeführt, dann wird sie trotzdem behandelt: Entweder wird Programm abgebrochen, oder die Ausnahme wird weitergereicht. Diese Fallunterscheidung ist in der Praxis einfacher, als es sich liest:

void benutzeGangschaltung() {

  try {
    legeRückwärtsgangEin();  // kann "WirSindMitVollgasVorwärtsUnterwegsAusnahme" werfen
  }
  catch( WirSindMitVollgasVorwärtsUnterwegsAusnahme x) {
    bremseFahrzeugBisStillstand();
  }
}

Ohne try-und-catch könnte manches Schlimme passieren.

Mehrere Ausnahmen können folgendermaßen abgefangen werden:

void benutzeGangschaltung() {

  try {
    legeRückwärtsgangEin();  // kann "WirSindMitVollgasVorwärtsUnterwegsAusnahme" werfen
    beschleunigeAuto();      // kann "WirFahrenGegenParkendesAutoAusnahme" werfen
  }
  catch( WirSindMitVollgasVorwärtsUnterwegsAusnahme |  WirFahrenGegenParkendesAutoAusnahme x) {
    bremseFahrzeugBisStillstand();
  }
}

Ausnahmebehandlung lässt sich auch anders verschachteln, etwa hintereinander oder ineinander. Aber das Grundprinzip ist immer das Gleiche.

Umwandelausnahme

Bearbeiten
public class Testklasse {
  public static void main(String[] args) {
    Integer i = 0;

    try {
      i = new Integer("12");
    }
    catch( NumberFormatException e ) {
      System.err.println("Der String konnte leider nicht umgewandelt werden!" + e.getMessage() + i);
    }
    System.out.println(i);
  }
}

Das vorstehende Beispiel benutzt genau die einfache Grundstruktur. NumberFormatException wird geworfen, wenn die Konvertierung eines Wortes in eine Zahl Integer("12") nicht erfolgreich war. Das Objekt e stellt die Methode getMessage() bereit, mit der der Fehler weiter beschrieben werden kann.

Natürlich wird eine Ausnahme nur dann geworfen, wenn tatsächlich ein Fehler passiert. So ein Fehler ist hier gezeigt:

public class Testklasse {
  public static void main(String[] args) {
    Integer i = 0;

    try {
      i = new Integer("zwölf");
    }
    catch( NumberFormatException e ) {
      System.err.println("Der String konnte leider nicht umgewandelt werden!" + e.getMessage() + i);
    }
    System.out.println(i);
  }
}

Selber werfen

Bearbeiten

Ausnahmen können Sie selber werfen. Das folgende Programm zeigt, wie es geht. Jede Methode, die eine Ausnahme wirft, sollte mit throws Ausnahme1, Ausnahme2, …, AusnahmeN gekennzeichnet werden.

class Weitwurf {

  public static String Σ(String a, String b) throws NumberFormatException {

    java.lang.Integer i, j, summe;

    try {
      i = new Integer(a);
    } catch (NumberFormatException e) {
      System.err.println(a + " konnte nicht in eine ganze Zahl gewandelt werden. ");
      throw e;
    }

    try {
      j = new Integer(b);
    } catch (NumberFormatException e) {
      System.err.println(b + " konnte nicht in eine ganze Zahl gewandelt werden. ");
      throw e;
    }

    /* wenn wir hier sind, lief alles glatt */
    summe = i + j;                                      // Summe bilden
    String ergebnis = Integer.toString(summe, 10);      // String Zahl zur Basis 10
    return ergebnis;
  }

  public static void main(String[] args) {
    String summe = "0";
    try {
      summe = Σ("12", "13");
    } catch (NumberFormatException e) {
      System.err.println("Mindestens einer der Summanden lässt sich nicht in eine Zahl umwandeln.");
    }
    System.out.println(summe);
  }
}

Die Funktion Σ(String a, String b) bereichnet die Summe der übergebenen Argumente, dazu werden die Argumente in Zahlen konvertiert (Integer(a)), anschließend addiert und wieder in einen Text konvertiert (Integer.toString(summe, 10)). Wenigstens der erste Teil ist weniger konstruiert, als es auf den ersten Blick erscheint. Selbstverständlich können Sie ein Programm schreiben, das die Kommandozeilenargumente aufaddiert und als String −vielleicht sogar zur Basis 2− ausgibt, oder? Wenn bei der Konvertierung etwas schief läuft, dann wird in diesem Beispiel per throw e die Ausnahme einfach erneut ausgelöst und somit an die aufrufende Funktion main weitergereicht. Modifizieren Sie obenstehendes Beispiel doch so, dass tatsächlich eine Ausnahme geworfen wird.

Schreib mit:

  • Wann ist finally {} hilfreich?
  • Wann wird der finally {}-Block betreten?
  • Beispiel

Schreib mit:

  • Was ist assert?
  • Wann ist es sinnvoll?
  • Was hat das mit Ausnahmen zu tun?

Eigene Ausnahmen schreiben

Bearbeiten

Es wird sie bestimmt überraschen, aber Ausnahmen sind ganz normale Objekte. Der Typ dieser Objekte ist eine Klasse, die von einer anderen Klasse die Eigenschaft erbt, eine Ausnahme zu sein. Und über Vererbung lassen wir uns erst später aus. Haben Sie noch etwas Geduld.