Home ORDIX AG             Dienstleistung             Trainingsshop    Kunden / Referenzen Aktuelles    Kontakt
Home  Pfeil  ORDIX News  Pfeil  4/2004
suche: 

ORDIX News Archiv

Das IT-Magazin der ORDIX AG mit Fachbeiträgen zu Datenbanken, Unix und Java/XML.

Weiterführende Links

Links
Seminarhinweis

Seminarhinweis:

Mit Java 5.0 Neuheiten bietet ORDIX ab dem ersten Quartal 2005 ein 2-tägiges Seminar zu diesem Thema an. Neue Seminare gibt es auch zum Thema J2EE, u. a.:
  • Web-Applikationsentwicklung mit JSP und Servlets
  • Applikationsentwicklung mit EJB
Schauen Sie einfach unter http://training.ordix.de.

Der Tiger ist los

Nachdem vor kurzem erst das Release Candidate von Java 1.5.0, genannt Tiger, von Sun veröffentlicht wurde, steht seit Ende September 2004 nun die endgültige Version zum Download bereit. Das fast 50 MB große Paket ist unter Java-Entwicklern seit langem ersehnt. Und das nicht wegen der üblichen Bugfixes und Erweiterungen an der Java-Bibliothek und der JVM, sondern wegen der angekündigten Spracherweiterungen. Diese sind Gegenstand dieses Artikels.

Ausgangsbasis

Wer schon länger in Java entwickelt, dem sind sicherlich einige Dinge aufgefallen, die unschön sind, weil sie entweder viel Tipparbeit erfordern, einfach nicht in gutes, objektorientiertes Design passen oder in anderen Programmiersprachen einfach eleganter gelöst sind. Und genau hier setzen die erwähnten Spracherweiterungen an. Dazu gehören:

Im folgenden werden diese Spracherweiterungen an konkreten Beispielen vorgestellt.

Generics

Java besaß bisher kein Sprachkonstrukt, welches mit den Templates in C++ vergleichbar wäre. Mit den Generics hat Sun dieses Manko behoben. Dahinter verbirgt sich die Möglichkeit, Collection- und Iterator-Instanzen mit Datentypen zu parametrisieren. Abbildung 1 zeigt als Beispiel im oberen Kasten die Nutzung einer ArrayList im herkömmlichen Sinne. Zu beachten sind die dabei notwendigen Casts, wenn Elemente direkt aus der ArrayList bzw. über einen Iterator entnommen werden.

Unter Nutzung der Generics entfällt in beiden Fällen der Cast, da die Elemente automatisch in den korrekten Datentyp umgewandelt werden. Der untere Kasten der Abbildung 1 stellt den Code mit Nutzung von Generics dar.

Das Ganze hat allerdings noch einen weiteren Vorteil. Die Typprüfung, also welche Elemente in eine Collection eingefügt werden, führt der Compiler während der Übersetzung durch. Damit gehört die bekannte java.lang.ClassCastException zur Laufzeit der Vergangenheit an.

Enhanced for-Loop

Die zweite Spracherweiterung befasst sich mit for-Schleifen, die zum Iterieren über Array- und Collection-Instanzen genutzt werden. Das ist zum einen mit Hilfe eines Index, zum anderen durch Nutzung eines Iterators möglich. Beide Fälle sind im oberen Kasten in Abbildung 2 zu sehen.

Greift man auf die neue for-Schleife zurück und kombiniert das Ganze mit der Verwendung von Generics, kann eine Menge Code eingespart werden. Die so "optimierten" for-Schleifen sind auch besser lesbar, wie der Vergleich der beiden Kästen in Abbildung 2 verdeutlicht.

Autoboxing/Unboxing

Ein Nachteil von Collections war bisher, dass sie nur Elemente von komplexen Datentypen aufnehmen konnten. Wollte man Elemente einfacher Datentypen wie int, long, char etc. einfügen, war bisher eine passende Wrapper-Instanz notwendig. Beim Entnehmen mussten die Elemente händisch "entpackt" werden, wie im oberen Kasten in Abbildung 3 zu sehen.

Mit dem Autoboxing/Unboxing-Feature ist das nun alles nicht mehr nötig. Das Einfügen und Entnehmen von Elementen eines einfachen Datentyps gestaltet sich so, als ob die Collection auch mit einfachen Datentypen umgehen könnte. Abbildung 3 zeigt im unteren Kasten die Vereinfachung.

Zu beachten ist allerdings, dass die verwendete Collection mit der zugehörigen Wrapper-Klasse, also z. B. Integer, parametrisiert wird. Dass dann natürlich keine anderen Elemente als int-Werte eingefügt werden können, ist einleuchtend.

Typesafe Enumerations

In switch/case-Anweisungen können hinter dem Schlüsselwort case nur Werte verwendet werden, die sich implizit in int-Werte wandeln lassen. Da diese wenig aussagekräftig sind, verwenden Entwickler oft int-Werte, die als statische Konstanten unter sprechenden Namen in einer Klasse definiert sind.

Dieses Vorgehen hat jedoch einige Nachteile. Die so definierten int-Enumerations

Darüber hinaus werden bei Ausgaben die int-Werte und nicht, wie eigentlich gewünscht, die Konstantennamen ausgegeben. Diese Nachteile lassen sich durch den Einsatz des Typesafe Enum Entwurfsmusters umgehen. Dieses muss allerdings immer individuell implementiert werden. Einfacher ist es, ab Java 1.5.0 die Typesafe Enumerations einzusetzen.

Einfache Typesafe Enumeration
Abb. 4: Einfache Typesafe Enumeration.

Eine Typesafe Enumeration wird durch das Schlüsselwort enum deklariert. Sie besitzt im einfachsten Fall einen Namen und besteht aus einer Element-Menge eben dieses Typs. Hierdurch wird die gewünschte Typsicherheit erreicht. In Abbildung 4 ist eine solche, einfache Typesafe Enumeration zu sehen.

Typesafe Enumeration mit Konstruktor, Methoden und Attributen
Abb. 5: Typesafe Enumeration mit Konstruktor, Methoden und Attributen.

Da es sich bei einer Typesafe Enumeration im Grunde um eine Klasse handelt, können innerhalb einer Typesafe Enumeration zusätzlich Attribute, Methoden und parametrisierte Konstruktoren definiert werden (siehe Abbildung 5). Damit ist es möglich, den Elementen weitere Eigenschaften zu zuweisen.

Typesafe Enumerations stellen also eine Implementierung des Typesafe Enum Entwurfsmusters auf Sprachebene dar. Die zugehörigen Elemente sind Instanzen. Sie besitzen einen Namensraum, sind typsicher, können mit Collection-Instanzen verwendet werden und geben bei der Ausgabe ihren Namen aus.

Bei der Implementierung von Typesafe Enumerations gilt es aber auch, ein paar Regeln zu beachten:

Static Import

Fast jede Java-Anwendung verwendet Konstanten. Diese sind oft zentral in einer Klasse statisch definiert. Das hat allerdings den Nachteil, dass bei der Nutzung dieser Konstanten der Klassenname vorangestellt werden muss (z. B. Constants.MAXSIZE).

Um das zu umgehen, besteht die Möglichkeit, die Konstanten innerhalb von Interfaces zu definieren, die ansonsten nichts deklarieren. Die Klassen, die diese Konstanten nutzen wollen, müssen anschließend das Interface implementieren. Dadurch können die Konstanten ohne vorangestellten Klassennamen genutzt werden. Obwohl diese Lösung funktioniert, ist sie aus sprachtechnischer Sicht zu verwerfen. Interfaces sind dazu da, um neue Typen zu deklarieren und nicht, um als Konstanten-Container zu dienen.

Damit solche Konstrukte nicht mehr nötig sind, gibt es in Java 1.5.0 die Spracherweiterung Static Import. Darunter versteht man den Import aller in der angegebenen Klasse enthaltenen Konstanten. Diese können anschließend ohne vorangestellten Klassennamen genutzt werden.

Um z. B. alle Konstanten, die in der Klasse de.ordix.java15.Constants definiert werden, zu importieren, genügt die folgende Anweisung: import static de.ordix.java15.Constants.*;

Zu beachten ist das Schlüsselwort static und die Erweiterung ".*" hinter dem Klassennamen.

Resümee

Mit den hier vorgestellten Spracherweiterungen nimmt Java dem Entwickler einen großen Teil der immer wiederkehrenden Tipparbeit ab. Und da Entwickler, wie allgemein bekannt, lieber weniger als mehr tippen, ist das sicherlich ein Schritt in die richtige Richtung. Das Resultat ist ein schlanker und eleganter Code, der darüber hinaus noch weniger unerwünschtes Laufzeitverhalten (Exceptions etc.) zur Folge hat.

Wer das Ganze schon jetzt ausprobieren will oder gar sofort umsteigen möchte, braucht die Java 1.5.0 und eine passende Entwicklungsumgebung. Ersteres stellt Ihnen Sun unter http://java.sun.com/j2se/1.5.0/index.jsp zum Download zur Verfügung. Als Entwicklungsumgebung bietet sich IntelliJ IDEA 4.5 an. Eine 30 Tage lauffähige Testversion kann im Internet unter http://www.jetbrains.com runtergeladen werden.

Zusätzlich finden Sie hier das IDEA-Projekt Java_1.5.0_Test als zip-Datei zum Download. Nach dem Entpacken in ein beliebiges Verzeichnis, kann das Projekt direkt aus IDEA geöffnet werden. Zu dem Projekt gehören die beiden Klassen NewFeatures.java und Constants.java, welche die hier vorgestellten Spracherweiterungen demonstrieren.

Bleibt uns nur noch, Ihnen viel Spaß mit dem Tiger zu wünschen!

Christoph Borowski (info@ordix.de).