JDT Entdeckertour: Sieben

Java-7-Support in den Java Development Tools

Marc Teufel
©Shutterstock/PictuLandra

Nach der Veröffentlichung von Java 7 haben auch die Entwickler der Java Development Tools (JDT) ihre Arbeiten am Java-7-Support abgeschlossen. Der Artikel stellt einige ausgewählte neue Funktionen aus Java 7 vor und zeigt, in welcher Form sie von JDT unterstützt werden.

Für die Eclipse IDE oder besser die Java Development Tools (JDT) war das Jahr 2011 in zweierlei Hinsicht ein aufregendes Jahr. Denn gleich zwei bedeutende Aktualisierungen der Entwicklungsumgebung fanden Platz auf Millionen Entwicklerrechnern: Den Anfang machte das jährliche JDT-Update im Juni [1], als im Rahmen von Indigo wieder viele neue Funktionen zur IDE hinzugekommen sind. Im Juli dann, mit der Freigabe von Java 7, folgte ein erneutes Update, durch das viele der neuen Möglichkeiten auch direkt in der Entwicklungsumgebung unterstützt werden.

JDT Entdeckertour
In der Serie „JDT Entdeckertour“ zeichnen wir die JDT-Verbesserungen von 2009 bis heute nach. Schauen Sie sich den einen oder anderen Trick bei der Arbeit mit Eclipse ab und entdecken Sie versteckte JDT-Funktionen, die Ihnen das Entwicklerleben leichter machen!

Serienteile:
Eclipse Galileo: Entdeckertour
– Eclipse Helios: Feinschliff
Eclipse Indigo: Immer noch ganz vorne dabei
– Eclipse Indigo: Sieben
Eclipse Juno: Alles gleich, doch vieles anders
– Eclipse Kepler: Durststrecke

Java 7

Java 7 hatte wahrlich lange auf sich warten lassen. Und auch wenn aufregende neue Funktionen wie Closures (und den interessanten Veränderungen in den Collection APIs) weiter auf sich warten lassen, hat Java 7 doch einige interessante Spracherweiterungen an Bord. Dabei hatte es der Java-7-Support nicht direkt in das Indigo Simultanrelease geschafft, das am 22. Juni 2011 veröffentlicht wurde. Doch hinter den Kulissen werkelten einige Entwickler der JDT fleißig an der Unterstützung für die nahende neue Java-Version, und so konnte man Ende Juli, nachdem Java 7 mit großem Tamtam [2] von Oracle veröffentlicht wurde, seitens Eclipse Foundation auch verkünden, dass der Java-7-Support in den Eclipse-Versionen 3.7.1, 3.8 und 4.2 enthalten sein wird. Für alle Indigo-Nutzer bedeutete das, auf das nächste Maintenance-Release (SR1) im September zu warten. Von da an fand der Java-7-Support auch in allen folgenden Simultanreleases Platz, zum ersten Mal in den Eclipse-Versionen 3.8 und 4.2 des Juno Release 2012. Gleich mit dem ersten Milestone wurde der Java-Support hier eingebaut. Diesem Artikel liegt der Milestone Build 1 von Eclipse 4.2 zugrunde. Folgende Features schauen wir uns an:

  • Strings in switch
  • Binary Integral Literals und Underscores in Numeric Literals
  • multi-catch
  • try-with-ressources
  • Diamond

Strings in „switch“

Jeder weiß: Lange Zeit konnte das switch-Statement von Java nicht mit Strings umgehen. Und die allermeisten dürften mittlerweile auch wissen: Seit Java 7 gehören diese Zeiten der Vergangenheit an. Vorbei die Zeiten, als man, wenn es darum ging, möglichst leserlich zu verzweigen, lange (dann doch wieder unleserliche) if-else-Blöcke geschrieben hat. Vorbei auch die Zeiten, als man Strings fantasievoll in Integers verpackt hat, um letztlich doch in den Genuss des switch-Statements kommen zu können (wobei der Name des Integers seiner String-Entsprechung möglichst nahe zu kommen hatte). Das man jetzt Strings in switch-Blöcken verwenden kann, bedeutet für die JDT erst mal, dass man Code wie in Listing 1 schreiben kann und die IDE diesen auch akzeptiert. Wem der eigentlich gut leserliche switch-Block aus Listing 1 doch nicht gefällt, oder wer Sehnsucht nach den guten alten Zeiten hat, der markiert einfach das switch-Statment und kann den neuen Quick Assist „Convert ‚switch‘ to ‚if-else‘“ verwenden, um wieder eine schöne  lange und unleserliche if-else-Darstellung daraus zu machen. Was viele nicht wissen, ist jedoch, dass die neuen Spracherweiterungen sich durch die ganze IDE ziehen. Das bedeutet, dass sie auch im Display View oder bei bedingten (conditional) Breakpoints voll unterstützt werden. Bezogen auf das Beispiel aus Listing 1 zeigt Abbildung 1, wie man das neue switch-Statement auch als Bedingung für einen Conditional Breakpoint einsetzen könnte.

public String foo(String what) {
   switch (what){
     case "Sohn":
        return "Timo/Tom";
     case "Frau":
        return "Daniela";
     case "Mutter":
        return "Monika";
     default:
        return "???";
  }
}

Abb. 1: Die Java-7-Spracherweiterungen sind überall in Eclipse verfügbar, hier bei Conditional Breakpoints

Binary Integral Literals und Underscores in Numeric Literals

Die Überschrift suggeriert, dass es sich dabei um eine recht komplexe neue Eigenschaft von Java handeln könnte. Doch weit gefehlt, es ist ganz einfach. Ein Literal ist in Programmiersprachen ein Wert, den man einer Variablen zuordnen kann. Numerische Literale sind also Zahlenwerte, binäre Literale halten Binärwerte vor. Wollte man früher mit Java-Mitteln einem Integer den Dezimalwert von binär 101010 (= 42) zuweisen, dann hat man das ungefähr folgendermaßen geschrieben: int binary = Integer.parseInt(„10101“,2);. Hier gibt der letzte Parameter der Funktion die Basis an. Die Methode ließe sich für Hexadezimalwerte also analog auch mit 16 im zweiten Parameter aufrufen, bei Dezimalzahlen würde der Wert logischerweise 10 lauten. So schön diese Methode auch ist, hat sie doch einen entscheidenden Nachteil: Sie ist schlecht lesbar. Daher kann man ab Java 7 binäre Werte alternativ auch wie folgt schreiben: int binary = 0b101010;. Das macht das Ganze sehr viel besser lesbar. Apropos lesbar, wie oft kommt es vor, dass man lange Zahlen in den Quellcode schreiben muss? Um auch lange Zahlen im Quellcode übersichtlicher darzustellen, ist es nun möglich, diese mit Underscores zu unterteilen.

Die neue Fassung der Java Devleopment Tools unterstützt sowohl die neue Schreibweise von Binärzahlen als auch die Möglichkeit, Underscores einzustreuen, vollständig. Mehr noch, sogar beim Debuggen, wo man Variablenwerte zur Laufzeit verändern kann, stehen die gerade besprochenen neuen Strukturierungsmöglichkeiten offen.

„multi-catch“

Das Programmieren von Fehlerbehandlung bedeutete früher nicht selten, dass man sich mit vielen Exceptions herumschlagen musste. Jede Exception war dabei in einem separaten catch-Block abzufangen. Die neue Java-Version bringt hier Vereinfachung, man kann jetzt nämlich unterschiedliche Exceptions in einem einzigen catch-Block behandeln. Und das Beste daran ist, dass Eclipse diese neue Funktion hervorragend unterstützt. Schreibt man beispielsweise Method m = getClass.getDeclaredMethod(„bar“); in den Editor, dann wird Eclipse die Zeile zunächst als fehlerhaft markieren. Fährt man mit der Maus über die Zeile, sieht man, dass Eclipse das fehlende Exception Handling bemängelt. Die Lösung zum Problem bietet Eclipse auch gleich in Form eines Quick Assist an: „Surround with try/catch“ und neu „Surround with try/multi-catch“. Der erste Quick Assist ist bereits länger vorhanden und umschließt das Statement mit einem try und mehreren catch-Blöcken pro abzufangende Exception. Anders ist es beim neuen Quick Assist (multi-catch), er erzeugt nur einen catch-Block und trennt die einzelnen Exceptions sauber mit einem senkrechten Strich. Das ist aber bei Weitem noch nicht alles, was die JDT in diesem Bereich zu bieten haben. Es stehen nämlich noch zahlreiche weitere Quick Assists zur Verfügung: Will man alten Code in das neue Format bringen, besteht mit dem Quick Assist „Combine catch blocks“ die Möglichkeit, einzelne catch-Blöcke zusammenzufassen. Andersherum kann man mit dem Quick Assist „Move exception to separate catch block“ einzelne Exceptions in eigene catch-Blöcke auslagern. Abbildung 2 zeigt einige Beispiele. Wenn eine Exception bereits in einem anderen catch-Block gefangen wird, zeigt Eclipse das übrigens auch an und gibt Möglichkeit zur Bereinigung. In den Preferences unter Java | Code-Style | Formatter lassen sich ferner verschiedene Einstellungen zum Line Wrapping für die Codegenerierung einstellen (Abb. 3).

Abb. 2: Verschiedene Quick Assists erleichtern den Umgang mit „multi-catch“

Abb. 3: Für „multi-catch“ und „try-with-ressources“ gibt es in den Preferences einige neue Formatter-Einstellungen

„try-with-ressources“

Hierbei handelt es sich um ein aufregendes Feature, denn es hilft, unseren Code nicht nur schlanker zu halten, sondern auch noch Fehler zu vermeiden. Im Rahmen von try-with-ressources kann man Ressourcen wie einen Reader oder ein JDBC-ResultSet in einem try-Block schachteln, wobei sich die Java-Laufzeitumgebung später automatisch darum kümmert, die Ressource zu schließen, sobald der umschließende Block verlassen wird. Der Blick auf Abbildung 4 sollte den Vorteil von try-with-ressources deutlich machen: Beide Versionen tun genau dasselbe, nämlich das Auslesen und Anzeigen einer Datei. In der Java-6-Version sind mehrere try-catch-Blöcke nötig und nicht zu vergessen (und was in der Praxis doch leider viel zu oft vergessen wird) der finally-Block, in dem die Datei wieder geschlossen wird. Selbstverständlich unterstützt JDT dieses neue Sprachkonstrukt vollständig. Beim Schreiben von try-with-ressources-Blöcken weist die IDE auch auf eventuell abzufangende Exceptions hin. Und auch hier kann bei Bedarf das bereits angesprochene multi-catch zum Abfangen mehrerer Exceptions zum Einsatz kommen. In den Code-Formatter-Einstellungen von Eclipse (Abb. 2) befinden sich außerdem einige Einstellungen zur Formatierung von try-with-ressources-Blöcken.

Übrigens, hinter den Kulissen ist das mit Java 7 eingeführte neue Interface java.lang.AutoClosable für das automatische Schließen der entsprechenden Ressource verantwortlich. Die Java-Laufzeitumgebung ruft nämlich automatisch beim Verlassen eines try-with-ressources-Blocks die Methode close() auf genau diesem Interface auf. Man kann durch Implementieren dieses Interface also auch selbst recht einfach eigene Ressourcen bauen, die sich dann im Rahmen von try-with-ressources selbst aufräumen beziehungsweise schließen.

Abb. 4: „try-with-ressources“ macht den Umgang mit Ressourcen deutlich leichter

Diamond

Seitdem Generics mit Java 5 eingeführt wurden, gibt es wahrscheinlich keinen ernsthaften Java-Programmierer mehr, der sie nicht verwendet hat. Mit Generics lassen sich Typvariablen definieren, was bedeutet, dass man etwa bei Collections schon beim Programmieren festlegen kann, welche Typen später in der selbigen Platz finden. Das schafft Typsicherheit und erleichtert damit die Programmierung an vielen Stellen. Trotzdem konnte das Schreiben von generischem Code auch lästig werden, denn es führt unweigerlich zu redundantem Code. So muss beispielsweise beim Anlegen einer einfachen typisierten Liste von String die Typendeklaration gleich zwei Mal geschrieben werden, nämlich einmal vor und einmal nach dem new-Operator: List<String> l = new ArrayList<String>();. Mit Java 7 ist das nun nicht mehr notwendig, die zweite Typendeklaration kann man jetzt einfach weglassen: List<String> l = new ArrayList<>();.

Eclipse unterstützt das Schreiben solcher Konstrukte, indem es auf der einen Seite diese so genannte Diamond-Syntax (alternativ ITIGIC für  „Improved type inference for generic instance creation“) beherrscht und der Content Assist beim Schreiben von Code von vorneherein die neue Syntax verwendet. In den Preferences unter Java | Compiler | Error/Warnings gibt es im Bereich Generic types ferner die neue Einstellungsmöglichkeit Redundant type arguments, die im Default (leider) auf Ignore gestellt ist. Wird diese auf Warning gestellt, dann markiert die IDE automatisch alle Stellen im Code mit einem Hinweis, wo man die Diamond-Syntax einsetzen könnte. Ein entsprechender Quick Assist (Remove type arguments) steht auch zur Verfügung, um überflüssige Typendeklarationen einfach und schnell zu entfernen. Eclipse unterstützt die Diamond-Syntax übrigens nicht nur bei der Zuweisung, sondern auch bei Methodenrückgaben, wobei hier der Typ der Methodendeklaration entnommen wird.

Fazit

Neben den beschriebenen Möglichkeiten unterstützt Eclipse außerdem die neue Annotation @SafeVarargs in Form diverser Quick Fixes. Ebenso ist Unterstützung für Unicode 6.0 und Polymorphic Methods enthalten. Detaillierte Beschreibungen zu allen Veränderungen und Erweiterungen im Zusammenhang mit Java 7 findet der interessierte Leser auch unter [3]. Abschließend bleibt festzustellen, dass beim Entwickeln des Java-7-Supports für JDT der Fokus klar auf den Spracherweiterungen lag. Alles in allem liegt mit der aktuellen Fassung der Java Development Tools damit eine solide Basis vor, mit der man bequem Java-Anwendungen für Java 7 schreiben kann.

Aufmacherbild: Autumn fall bright orange leaves number von Shutterstock / Urheberrecht: ©Shutterstock/PictuLandra

Geschrieben von
Marc Teufel
Marc Teufel
Marc Teufel arbeitet als Projektleiter und Softwarearchitekt bei der hama GmbH & Co KG und ist dort für die Durchführung von Softwareprojekten im Bereich internationale Logistik zuständig. Er ist Autor zahlreicher Fachartikel im Web-Services- und Eclipse-Umfeld. Er hat drei Bücher zu Web Services veröffentlicht, sein aktuelles Buch „Eclipse 4 – Rich Clients mit dem Eclipse 4.2 SDK“ ist kürzlich bei entwickler.press erschienen.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.