Java schafft Checked Exceptions ab

01.04.2022

Anfangs hielt man Checked Exceptions für eine gute Idee. Doch schon bald zeigte sich, dass sie in der Praxis nicht so funktionierten wie erhofft. Programmiersprachen, die nach Java entstanden sind, haben das Konzept nicht übernommen. Nun steht auch für Java das Ende der Checked Exceptions bevor.

Gut gemeint, aber…

Hierarchie der ExceptionsIn der Theorie hört sich das Konzept schlüssig an: wenn beim Aufruf einer Methode zu erwarten ist, dass eine bestimmte Art von Fehler auftreten kann, wird dies durch ein „throws“-Statement in der Methodendeklaration explizit gemacht. Im Falle der Checked Exceptions (siehe Grafik) prüft der Compiler, ob die im Methodenkopf deklarierten Exceptions abgefangen oder weiter geworfen werden. Ist keins von beidem der Fall, kompiliert das Programm nicht. So sind die Entwickler:innen gezwungen, sich Gedanken darüber zu machen, was im Fehlerfall passieren soll, und ein entsprechendes Fehlerhandling zu programmieren.

Leider ging der Plan nicht auf wie erwartet. Oft gibt es an der Stelle, wo eine Checked Exception abgefangen wird, nicht die Möglichkeit, bzw. dem/der Entwickler/in fehlt das notwendige Know-how, um eine sinnvolle Fehlerbehandlung zu implementieren. Oder man macht sich einfach nicht die Mühe und ignoriert die Exception.

Auswertung der Exception-Handling-MethodenEine Analyse von 600.000 Javaprojekten zeigt auf, was die häufigsten „Fehlerbehandlungen“ in catch-Blöcken von Checked Exceptions sind:

Dicht gefolgt auf das Loggen der Exception oder dem Aufruf von e.printStackTrace() steht ein leerer catch-Block – also keine Behandlung, sondern das „Verschlucken“ des Fehlers! Die nächsthäufigste Behandlungsmethode ist das Wrappen in eine Unchecked Exception. In den wenigsten Fällen wird die Exception via throws direkt weiter geworfen.

Checked Exceptions: das wohl umstrittenste Java-Feature überhaupt

Checked Exceptions waren von Beginn an umstritten. Im Internet gibt es viele Argumente sowohl dafür, als auch dagegen. Doch im Laufe der Zeit gewann das Lager der Gegner immer größeren Zuspruch.

So gut wie alle Sprachen, die nach Java entwickelt wurden, haben das Feature nicht übernommen. Beispiele dafür sind u.a. Scala und Kotlin. In diesem Interview mit Bruce Eckel erklärt Bill Venners, Lead-Architekt von C#, wieso das Entwicklungsteam sich gegen Checked Exceptions entschieden hat. Als einen der Gründe führt er an, dass die Weiterentwicklung von APIs dadurch erschwert wird: bekommt eine bestehende Methode eine neue throws SomeCheckedException-Deklaration hinzu, kompiliert nach einem Versionsupdate sämtlicher Code nicht mehr, der diese API-Methode nutzt.

Aber auch in Java-Frameworks, wie beispielsweise Spring, wurde die bewusste Designentscheidung getroffen, ausschließlich Runtime Exceptions zu verwenden.

Bereits 2009 schreibt Miško Hevery, Coach bei Google für eine Kultur für hochautomatisiertes Testen, im Google Testing Blog, wieso Checked Exceptions gehen müssen.

Java Champion Mario Fusco fasst das Thema auf Twitter schließlich wie folgt zusammen: „What Java devs do in checked exception catch blocks demonstrates that if you oblige a dev to do smtg unnecessary he will do smtg stupid“

Die Konsequenz

Diese Entwicklung nehmen sich die Sprachdesigner von Java nun zu Herzen. In JEP-1422 wird die Abschaffung der Checked Exceptions beschrieben. Die Umsetzung ist im Grunde ganz einfach: Lediglich die Compilerprüfung, der bisher als Checked Exceptions geführten Ausnahmen, wird entfernt. Die try / catch – Blöcke sowie das throws Statement bleiben erhalten. Auch an der Hierarchie der Exception-Klassen wird sich nichts ändern – mit Ausnahme der Semantik, denn künftig werden auch Exception und all ihre Subklassen, die nicht von RuntimeException erben, Unchecked Exceptions sein. Das heißt sie können, müssen aber nicht via throws deklariert werden, und müssen nicht in einem catch-Block abgefangen werden.

Java Language Architect Brian Goetz schreibt dazu: „Unlike with language extensions, this is a relatively simple matter. If you take something away, the risk to introduce breaking changes is a lot lower as if you make additions to a language.“

In welches Java-Release die Änderung Einzug halten wird, ist derzeit noch nicht abzusehen. Wie üblich wird es auch hierfür ein oder möglicherweise mehrere Previews geben, die zum Testen per Kommandozeilenparameter freigeschaltet werden müssen. Ein Erscheinen vor Java 20 ist demnach unwahrscheinlich.

Details zu der Sprachänderung finden sich unter JEP-1422.

 

Mehr zu Java Programmierung erfahren

Zurück zur Übersicht

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*Pflichtfelder

*