Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

Java 7 Grundkurs

handle or declare, RuntimeExceptions

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Lernen Sie mehr über "fangen und behandeln", die "handle und declare"-Regel und warum diese bei Runtime-Exceptions nicht zutrifft. Sehen Sie Näheres dazu im Beispiel und Chart.
08:28

Transkript

Wenn in einer Methode eine "Exception" auftritt, dann kann sie diese fangen und behandeln, also mit "Try und Catch", oder nach oben durchreichen. Diese "handle or declare"-Regel, also "behandle oder deklariere", schauen wir uns jetzt mal etwas genauer an. Ich verwende dazu dieses Beispielprojekt "Eigene Exception". Darin wird zuerst einmal eine eigene "Exception" deklariert, die heißt "GefährlichesIstPassiertException" und das ist eine Unterklasse von "Exception". Verwendet wird diese"Exception" in der Klasse "GefährlichesDing". Hier gibt es eine gefährliche Methode, die eine riskante Operation ausführt und, wenn diese schief läuft, eine "GefährlichesIstPassiertException" wirft. Das geschieht mit dem Schlüsselwort "throw". In der Hauptklasse dieser Anwendung "EigeneExceptionDemo", wird nun ein solches "GefährlichesDing" erzeugt und die "gefährlicheMethode()" aufgerufen. Dieser Aufruf ist in einen try-Block eingeschlossen, so dass die "GefährlichesIstPassiertException" mit einem Catch gefangen werden kann. Die komplexe Behandlung des Fehlers habe ich hier mal weggelassen. Es wird lediglich eine kurze Meldung ausgegeben, dass ein Fehler aufgetreten ist, in Verbindung mit der Nachricht, die aus der "Exception" rausgeholt wird. Schließlich, nachdem die "Exception" gefangen und erfolgreich behandelt wurde, gibt es noch eine weitere Statusmeldung. Wenn wir die Anwendung ausführen, wird also diese "gefährlicheMethode()" aufgerufen, die "Exception" wird geworfen, sie wird hier gefangen, die Meldung wird ausgegeben und schließlich die zweite Meldung. Ich mache das mal und dann sehen wir: Fehler und alles wieder gut. Nun schieben wir zwischen unsere main-Methode und das "GefährlicheDing" noch ein weiteres Objekt. Dazu deklarieren wir uns eine neue Klasse. Ich klicke also auf das Package, mit der rechten Maustaste, sage "New Java Class", und dies wird ein normales Ding. Paketname stimmt, "Finish", und die Klasse wird erzeugt. Dieses "NormaleDing" hat eigentlich mit Problemen nichts am Hut und hat deswegen auch nur eine ganz normale Methode. In dieser normalen Methode passieren normale Dinge, doch dann wird hier ein "GefährlichesDing" instantiiert. Natürlich wird dann von diesem Ding die "gefährlicheMethode()" aufgerufen. Schauen wir uns nochmal kurz die Deklaration dieser Methode an. Dazu können wir mit Strg+Klick direkt hinspringen. Sie sehen hier: Diese Methode deklariert, dass sie eventuell eine "GefährlichesIstPassiertException" werfen könnte. Der Aufrufer dieser Methode ist nun also gewarnt und hat jetzt zwei Möglichkeiten. Entweder er behandelt diese "Exception" vor Ort, oder er reicht sie an seinen Aufrufer hoch. Dieses Aufrufen muss er natürlich nicht selbst machen, das macht die Java-Laufzeitumgebung. Aber diese Methode hier muss deklarieren, dass sie eventuell eine "Exception" hochreichen könnte. Das ist die "handle or declare"-Regel. "Exception" vor Ort behandeln, oder hier deklarieren, dass die hochgereicht werden könnte. Das Wesentliche dabei ist: Der Compiler überwacht die Einhaltung dieser Regel. Wenn wir also eine Methode aufrufen und die entstehende "Exception" weder behandeln noch deklarieren, dann bekommen wir einen Compilerfehler. Und der heißt dann: "Unreported Exception:  GefährlichesIstPassiertException" muss gefangen werden oder deklariert werden. Die Entscheidung für eine der beiden Möglichkeiten ist eigentlich recht einfach. Wenn wir an dieser Stelle im Programm ausreichendes Wissen und ausreichende Fähigkeiten haben die "Exception"zu behandeln, dann tun wir das. Ansonsten reichen wir sie hoch. Eine "Exception" sollte immer da gefangen werden, wo sie auch behandelt werden kann. Unser "NormalesDing" hat eigentlich mit Fehlerbehandlung nichts am Hut, möchte sich also auch um das "Exception-Handling" nicht kümmern müssen. Dann ist alles, was diese Methode tun muss, hier oben zu deklarieren: "Achtung, hier könnte eine "Exception" kommen!" Also ein "throws" und dann -- Strg+Leertaste hilft -- "GefährlichesIstPassiertException". Wir sehen: In der Methode steht nichts von Fehlerbehandlung, von Rückgabewerte entgegennehmen und hochreichen, und so weiter. Die Methode enthält also nur den Code, den wir auch tatsächlich ausführen möchten. Sollte nun aus einer dieser Anweisungen eine "Exception" entstehen, dann wird diese einfach automatisch hochgereicht, an den Aufrufer dieser Methode. Dafür muss der Programmierer nichts weiter tun, das macht die Laufzeitumgebung. Nun gehen wir noch einmal in unsere Hauptklasse. Ich schiebe das hier mal alles etwas nach unten und erzeuge mir hier jetzt ein "NormalesDing". Nun rufe ich, nichts Böses ahnend, die "normaleMethode()" auf, und wie wir sehen, weist mich der Compiler sofort darauf hin: "Achtung, hier könnte eine "Exception" kommen!" Das weiß er, weil das ja an der Methodendeklaration hinten dransteht. Auch hier bei diesem Aufruf müssen wir uns nun wieder an die Regel halten, also entweder behandeln oder deklarieren. Da wir hier aber in der main-Methode sind, gibt es keine Methode mehr, die noch eins höher ist, an die wir also die "Exception" hochreichen könnten. Wenn wir sie also nicht hier behandeln, dann platzt das Programm. Also machen wir hier einen Try/Catch drumherum. Das können wir natürlich von der IDE machen lassen. Hier auf das gelbe Lämpchen klicken, und dann haben wir hier "Surround statementwith Try/Catch". Der Methodenaufruf wird also wieder in einen try-Block eingeschlossen, dann kommt ein Catch für "GefährlichesIstPassiertException", und hier können wir jetzt unsere Fehlerbehandlung einbauen. Die kennen wir ja schon, und zwar geben wir hier eine Statusmeldung aus -- und gut ist. Wie wir also gesehen haben, achtet der Compiler darauf, dass keine "Exception" irgendwo verloren geht. Jede "Exception" muss entweder vor Ort behandelt werden, oder es muss deklariert werden, dass sie an den Aufrufer hochgereicht werden würde, wenn sie entsteht. Wenn wir Klassen aus der Standardbibiliothek verwenden, können wir in der API-Dokumentation nachschauen, ob die Methoden, die wir gerne aufrufen möchten, "Exceptions" werfen könnten, und wenn ja, welche. Nehmen wir z.B. diese Klasse INTEGER. Da gibt es eine Methode, die heißt "parseInt()", hier -- klicke ich mal drauf, dann habe ich Detailbeschreibungen. Und hier sehen wir: Diese Methode "parseInt()", die nimmt einen String, gibt ein Int zurück, sie macht aus dem String eine Zahl. Und dann steht dahinter: "throws NumberFormatException". Hier steht es noch mal genau: "throws NumberFormatException" und zwar, wenn der String sich nicht in eine Zahl konvertieren lässt. Es steht also alles da, man muss das nicht auswendig lernen. Und wenn man es doch mal vergisst, sich um eine "Exception" zu kümmern, wird man vom Compiler darauf hingewiesen. Allerdings gibt es eine Ausnahme von dieser Regel. Und diese Ausnahme heißt "RuntimeException". Die Basisklasse all unserer "Exceptions" heißt ja "Exception". Und dann haben wir Unterklassen wie "IOException" oder "SQLException". Eine spezielle Unterklasse heißt "RuntimeException". Die anderen "Exceptions" zeigen ja normalerweise an, dass wir eine geplante Abweichung vom normalen Programmverlauf haben, die wir gern fangen und behandeln können möchten. "RuntimeExceptions" hingegen zeigen in der Regel an, dass wir einen Programmierfehler haben. Das können wir schon an den Namen der "Exceptions" ablesen. Wir haben hier z.B. die "NullPointerException". Die tritt auf, wenn wir versuchen über eine Referenzvariable, z.B. eine Methode aufzurufen, aber diese Referenzvariable verweist auf gar kein Objekt, sondern sie ist NULL. Das ist, würde ich sagen, ein typischer Programmierfehler. "ClassCastExceptions" treten auf, wenn wir versuchen eine Typumwandlung vorzunehmen, die das Objekt nicht zulässt, also wenn wir z.B. versuchen einen String auf einen Toaster zu casten. Auch das ist in der Regel ein typischer Programmierfehler. Und die "ArrayIndexOutOfBoundsException", die übrigens ein schönes Beispiel für einen sprechenden Bezeichner ist, ist ebenfalls in der Regel auf einen Programmierfehler zurückzuführen. Sie tritt nämlich auf, wenn ich versuche, in einem Array auf ein Element mit einem ungültigen Index zuzugreifen, z.B. "-5". Es gibt noch eine ganze Reihe weiterer "RuntimeExceptions", das hier ist nur eine kleine Auswahl. Abgesehen von einzelnen Ausnahmen, wie z.B. "NumberFormatException", die nämlich auch eine "RuntimeException" ist, entstehen diese typischerweise aus Programmierfehlern. Deshalb sollten sie nicht mit Try/Catch gefangen und behandelt werden, sondern viel besser behoben. Sie treten also häufig während der Testphase des Programms auf, sollten dann aber nach und nach ausgemerzt werden. Diese "RuntimeExceptions" stellen nun eine Ausnahme von der "handle or declare"-Regel dar. Für sie gilt diese Regel schlicht nicht. Wäre das nicht so, dann wäre der gesamt Java-Code zugepflastert von "Tries and Catches", denn jedes mal, wenn ich irgendwo eine Referenzvariable verwende, riskiere ich ja eine "NullPointerException". Und jedes mal, wenn ich in einem Array auf ein Element zugreife, dann riskiere ich ja theoretisch eine "ArrayIndexOutOfBoundsException". Ich müsste also all diese Zugriffe immer mit Try/Catch umschließen, und jede Methode müsste deklarieren "throws "NullPointerException", "ArrayIndexOutOfBoundsException", und so weiter. Der Code wäre völlig unlesbar und auch unwartbar. Deshalb drückt der Compiler bei "RuntimeExceptions" quasi ein Auge zu. Das heißt, sie müssen diese weder abfangen noch deklarieren. Sie können das zwar machen, aber Sie müssen das nicht. Das heißt auch: Sie bekommen keinen Compilerfehler, wenn Sie es nicht tun. Sie haben nun also gesehen, was es mit der "handle or declare"-Regel auf sich hat und wann diese nicht zutrifft, nämlich bei "RuntimeExceptions".

Java 7 Grundkurs

Machen Sie sich mit den Grundlagen der Java-Programmierung vertraut und lernen Sie die Syntax der Sprache sowie das Konzept der objektorientierten Softwareentwicklung kennen.

8 Std. 32 min (66 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!