Mittwoch, 9. Oktober 2013

Checked Exceptions vs Interfaces

So genannte "Checked Exceptions" sind Ausnahmen in Java, die auf jeden Fall vom Programmierer behandelt werden müssen. Tut er das nicht, wirft der Compiler einen Fehler und verweigert die Übersetzung. Am Konzept der Checked Exceptions gibt es reichlich Kritikpunkte. Java selbst versucht in dem entsprechenden Tutorial das Konzept zu verteidigen. Besonders pikant ist aber, dass das Konzept der Checked Exceptions in Widerspruch steht zu einem anderen Konzept von Java und zwar den "Interfaces". Bei einem Interface handelt es sich um eine abstrakte Spezifikation eines Verhaltens, das unabhängig von der Art der Implementation ist. Das Interface weiß also nichts darüber, wie es implementiert sein könnte. Somit kann das Interface auch nicht wissen, ob bei einer Implementation eine Ausnahme auftreten kann und wenn ja welche. Das wiederum bedeutet, dass ein Interface gar keine Ausnahmebehandlung vorsehen kann, da dem Interface gar nicht klar sein kann, welche Fehler bei der jeweiligen Implementation auftreten könnten.

Java definiert seit der Version 1.5 das Interface "Appendable". Dieses Interface spezifiziert den Vorgang des Anhängens einer Zeichenkette an ein Objekt mittels der Methode append. Merkwürdigerweise sind alle drei Varianten von append so definiert, dass sie eine IOException werfen können. Das wirft die Frage auf, woher das Interface weiß, dass bei seiner Implementation eine IOException auftreten kann, obwohl der Sinn eines Interfaces darin besteht, dies gar nicht wissen zu dürfen? Die Antwort liegt in der hellseherischen Fähigkeit dieses Interface. Bei der Definition des Interfaces ging man davon aus, dass es mal eine Implementation geben könne, die beim Vorgang des Anhängens eine IO-Operation ausführen müsste. Und genau das würde das Entstehen einer IOException ermöglichen. Wenn man also vom Konzept der Checked Exceptions nicht abrücken will, muss man das Interface so gestalten, dass alle theoretisch denkbaren Checked Exceptions vorhergesehen werden um sie im Interface definieren zu können. Ein derartiges Anliegen ist natürlich völliger Unsinn.

Ergebnis dieses konzeptionellen Widerspruchs ist, dass man das Interface Appendable mit eigenen Checked Exceptions, die die Designer von Java leider nicht vorhergesehen haben, gar nicht implementieren kann. Das wiederum bedeutet, dass man in einer Implementation von Appendable alle Checked Exceptions in Unchecked Exceptions umwandeln muss. Und das wirf dann die Frage auf: wozu das eigentlich? Insbesondere wenn man sich vor Augen führt, dass Appendable kein Einzelfall ist. Das Problem tritt in gleicher Weise beim Iterator auf. Und obwohl der Iterator schon seit Version 1.2 mit an Bord ist, war man damals immerhin so schlau, sich die Blöße mit der IOException gar nicht erst zu geben. Das Iterator-Interface definiert keine implementationsspezifischen Ausnahmen, obwohl natürlich sonnenklar ist, dass auch beim Iterieren IOExceptions auftreten können.

Am Ende stellt sich dann die Frage: auf was will man lieber verzichten: Interfaces oder Checked Exceptions? Ich für meinen Teil bin der Meinung, wer Checked Exceptions benutzt ist selber Schuld.

Dienstag, 8. Oktober 2013

Java inherits Common Lisp´s name spaces

Java puts classes and variables in different name spaces. This is a bit like Common Lisp where functions have also their own name space. Common Lisp has been criticized for this and has been called ugly. Oracle´s Java 1.7 does it the same and compiles the following example without any complain:
class names
{
  public static void main (String[] args)
  {
    names names = new names();
  }
}