Eine Lernzielkontrolle zu Exceptions (in Java) gibt es in der neunundsiebzigsten Episode des Anwendungsentwickler-Podcasts.
TL;DR
Mit meiner Lernzielkontrolle zu Exceptions kannst du dein Wissen über Fehler beim Programmieren prüfen und dich auf Fragen im Fachgespräch vorbereiten. Eine Exception kennzeichnet eine Ausnahmesituation und unterbricht den normalen Programmfluss, bis ein passender catch-Block sie auffängt. An Java zeige ich dir, wie du Exceptions gezielt behandelst oder weiterreichst, was Checked Exceptions bedeuten und wie try-with-resources Ressourcen automatisch schließt. Der Stacktrace hilft dir, Fehler zu finden; weil sein Erzeugen Aufwand verursacht, gehören Exceptions in die Ausnahmebehandlung.
Kapitelmarken
[00:00:01] Hinweis zum Fachgespräch
[00:00:37] Lernzielkontrolle zu Exceptions mit Java
[00:02:38] Fragen fürs Fachgespräch und ergänzendes Hörbuch
[00:03:30] Was eine Exception ist
[00:05:03] Die Analogie vom Werfen und Fangen
[00:06:38] Exceptions behandeln oder weiterreichen
[00:08:38] Die passende Stelle für den Umgang mit Fehlern
[00:10:49] Exceptions mit try und catch auffangen
[00:12:30] finally und das Schließen von Ressourcen
[00:15:39] try-with-resources und AutoCloseable
[00:17:13] Exceptions mit throw auslösen
[00:19:53] throws und Checked Exceptions
[00:22:10] Mehrere Exception-Typen gezielt auffangen
[00:23:36] Unchecked Exceptions
[00:25:46] Eigene Exception-Klassen und zusätzliche Attribute
[00:27:54] Call-Stack und Stacktrace bei der Fehlersuche
[00:30:38] Aufwand von Exceptions und regulärer Programmablauf
[00:32:08] Die Java-Hierarchie mit Throwable, Error und Exception
[00:35:08] Was Exceptions beim Umgang mit Fehlern ermöglichen
[00:37:42] Prüfungsbezug und Quellen zum Vertiefen
[00:39:50] Hörbuch-Tipp: What If von Randall Munroe
[00:41:20] Ausblick auf weitere Lernzielkontrollen
Inhalt
Exceptions
Was ist eine "Exception"?
Eine unerwartete Ausnahmesituation in einem Programm, meistens ein Fehler.
Oder: Die Klasse, die dieses Konzept in der Programmiersprache repräsentiert.
Was ist die Analogie zur Erklärung der Behandlung von Exceptions?
Man "wirft" und "fängt" Exceptions wie einen Ball.
Wie kann man grundsätzlich mit Exceptions umgehen?
Man kann sie entweder direkt fangen (und das Problem lösen) oder dies an den Aufrufer delegieren (weiterwerfen).
Wie behandelt man eine Exception in Java?
Mittels try, catch und finally.
Wann braucht man einen finally-Block?
Wenn eine Operation unter allen Umständen nach try/catch ausgeführt werden muss (insb. wenn im catch-Block potentiell auch Fehler auftreten können).
Was ist try-with-resources?
Ein Sprachkonstrukt in Java, das dafür sorgt, dass Ressourcen nach ihrer Nutzung sauber wieder geschlossen werden, egal ob eine Exception auftritt oder nicht. Die Ressource muss dafür java.lang.AutoCloseable implementieren. Entspricht using in .NET.
Was macht das Schlüsselwort throw?
Wirft eine Exception.
Was macht das Schlüsselwort throws?
Markiert eine Methode als potentiell fehleranfällig und zwingt den Aufrufer zur Fehlerbehandlung.
Was ist der Unterschied zwischen "checked" und "unchecked" Exceptions?
Checked Exceptions (die es nur in Java gibt), müssen behandelt werden (der Compiler prüft das). Unchecked Exceptions (z.B. nicht vorhersehbare Laufzeitfehler wie "Speicher voll") müssen nicht behandelt werden.
Wie erzeugt man seine eigenen Exceptions?
Man kann eigene Klassen von Exception erben lassen. Diese können dann auch "echte" Attribute und Methoden beinhalten.
Was ist der "Call Stack"?
Der Aufrufstack enthält die Rücksprungadressen aller im bisherigen Programmablauf aufgerufenen Methoden. Darüber kann man nachvollziehen, wie das Programm zur aktuellen Position gelangt ist. Jede Exception hat den Call Stack bis zu ihrem Auftreten als Attribut.
Sollte man Exceptions zur Steuerung des Programmablaufs einsetzen?
Nein, da Exceptions - z.B. wegen des Call Stacks - recht "teuer" sind.
Wie sieht die Hierarchie von Exceptions in Java grob aus?
Throwable: Basisklasse aller Exceptions in Java.
Error: "Echte" Fehler, die ein Programm normalerweise nicht behandeln kann (z.B. StackOverflowError).
Exception: Fehler, die das Programm behandeln können sollte.
RuntimeException: Unchecked Exceptions wie z.B. ArithmeticException bei Division durch 0.
Was sind die Vorteile von Exceptions gegenüber direkter Fehlerbehandlung?
Produktivcode und Fehlerbehandlungscode werden stärker getrennt.
Man kann das Behandeln von Fehlern an den Aufrufer delegieren.
Man kann einfacher zwischen verschiedenen Fehlern unterscheiden.
Literaturempfehlungen
Die Java-Insel* beschreibt in einem eigenen Kapitel ausführlich den Umgang mit Exceptions in Java (siehe Exceptions).
*(direkt beim Rheinwerk-Verlag bestellen*)
Und auch Clean Code* enthält ein komplettes Kapitel zum Umgang mit Exceptions und Fehlersituationen.
*
Meine Hörbuch-Empfehlung der Woche: What if?* von Randall Munroe
*
Links
Permalink zu dieser Podcast-Episode
RSS-Feed des Podcasts
Lesson: Exceptions (The Java Tutorials - Essential Classes)
The try-with-resources Statement (The Java Tutorials - Essential Classes - Exceptions)
Call stack - Wikipedia, the free encyclopedia
Exception Hierarchy in Java
The Truth Behind the Big Exceptions Lie | Java Code Geeks - 2016
Zusammenfassung
Exceptions als Thema für IT-Azubis
Für meine IT-Azubis ergänze ich die Aufgaben aus dem Java-Tutorial mit Lernzielkontrollen. Die Fragen zu Exceptions eignen sich auch, wenn du dich als Fachinformatiker:in Anwendungsentwicklung auf dein Fachgespräch vorbereitest. Fehler beim Programmieren zu behandeln, ist ein allgemeines Thema; die technischen Details beziehen sich hier auf Java. Auch C# und Ruby kennen Exceptions.
Was eine Exception bedeutet
Wenn während eines Programmlaufs eine unerwartete Situation auftritt, spricht man von einer Exception, also einer Ausnahme. Der Begriff bezeichnet außerdem die Klasse beziehungsweise das Objekt, das diese Situation im Programm repräsentiert. Eine Ausnahme kann durch einen Fehler entstehen oder durch ein Verhalten, das vom erwarteten Ablauf abweicht.
Beim Umgang mit Exceptions hilft das Bild eines Balls: Ich werfe eine Exception, die an einer passenden Stelle aufgefangen wird. Dazu passen die Schlüsselwörter throw und catch.
Exceptions auffangen und weiterreichen
Du kannst eine Exception dort auffangen, wo dein Code sinnvoll auf sie reagieren kann. Wenn sich die Datenbank vorübergehend nicht erreichen lässt, kann ich beispielsweise fünf Sekunden warten und erneut versuchen, mich zu verbinden. Nach einem erfolgreichen Versuch läuft das Programm weiter.
Bleibt die Datenbank unerreichbar, reicht die Methode den Fehler an die aufrufende Methode weiter. Eine grafische Oberfläche kann daraufhin der/dem Benutzer:in eine verständliche Meldung anzeigen.
Exceptions wandern automatisch durch den Call-Stack, bis ein passender Block sie auffängt. Dadurch kannst du die Stelle, an der ein Fehler entsteht, von der Stelle trennen, an der dein Code darauf reagiert. Entscheidend ist, welche Methode mit der konkreten Situation umgehen kann.
Ein zentraler catch-Block in der main-Methode kann Exceptions auffangen, die bis dorthin gelangen. Ich empfehle, Fehler gezielt an einer geeigneten Stelle zu behandeln, weil beim Auffangen in main häufig nur noch das Beenden des Programms bleibt.
Wie try, catch und finally arbeiten
In einem try-Block steht Code, bei dem eine Exception auftreten kann. Für eine Datenbankabfrage würde ich dort die entsprechenden Aufrufe unterbringen.
Sobald eine Exception auftritt, wird der normale Ablauf an dieser Stelle unterbrochen. Das Programm sucht einen passenden catch-Block und führt dessen Code aus. Wenn der try-Block erfolgreich durchläuft, wird der catch-Block übersprungen. Eine unbehandelte Exception kann zum Programmabbruch führen und auf der Konsole ausgegeben werden.
Der optionale finally-Block wird beim Verlassen dieser Struktur ausgeführt, auch wenn während des Ablaufs oder im catch-Block eine Exception auftritt. Dort kann ich Ressourcen schließen, die nach dem Zugriff wieder freigegeben werden müssen. Das betrifft beispielsweise eine geöffnete Datenbankverbindung.
Auch beim Schließen einer Verbindung kann eine weitere Exception entstehen. Code, der erst hinter der gesamten try-catch-Struktur steht, wird in einem solchen Fall möglicherweise übersprungen. Für Aufräumarbeiten ist deshalb der finally-Block vorgesehen.
Ressourcen automatisch schließen
Wenn ich mit Ressourcen arbeite, verwende ich in Java try-with-resources. Die Ressource wird in den Klammern hinter try angegeben und am Ende automatisch geschlossen, auch wenn eine Exception auftritt.
Das eignet sich etwa für Datenbankverbindungen und Dateihandles. Voraussetzung ist, dass die Ressource das Interface java.lang.AutoCloseable implementiert. In C# gibt es mit dem using-Block eine entsprechende Möglichkeit.
Mit throw eine Exception auslösen
Durch throw löst du selbst eine Exception aus. Dahinter steht das Objekt, das geworfen wird, beispielsweise eine neu erzeugte Instanz einer Exception-Klasse.
Ich gebe einer Exception eine aussagekräftige Fehlermeldung und wähle einen passenden Typ. Eine DatabaseNotAvailableException macht erkennbar, dass die Datenbank fehlt. Ein darauf abgestimmter catch-Block kann gezielt auf diesen Fehler reagieren.
throws und Checked Exceptions
Mit throws gibst du an einer Java-Methode an, welche Exceptions beim Aufrufen auftreten können. Mehrere Typen lassen sich dort ebenfalls aufführen.
Bei Checked Exceptions prüft der Compiler, ob die aufrufende Methode mit den möglichen Fehlern umgeht. Dafür gibt es zwei Wege:
Du fängst die Exception mit einem passenden catch-Block auf.
Du reichst sie weiter und führst sie im throws-Teil der aufrufenden Methode auf.
Der Compiler weist dadurch auf fehlende Schritte beim Umgang mit diesen Exceptions hin. Wenn ich sie durch viele Methoden weiterreiche,...