zurück zum Artikel

Was ist neu in Java 7? Teil 1 – Produktivität

Markus Eisele

Auf der Suche nach einer beinahe endlosen Geschichte mag man auch über Java 7 stolpern. Viereinhalb Jahre nach Freigabe der letzten Java-Version soll dieses am 28. Juli erscheinen. Zeit, sich die Produktivitätsfeatures genauer anzuschauen.

Auf der Suche nach einer beinahe endlosen Geschichte mag man auch über Java 7 stolpern. Nachdem die Version 6 der Java Standard Edition (Java SE) am 11. Dezember 2006 erschienen war, soll vier Jahren, sieben Monate und voraussichtlich 17 Tage später der früher unter dem Codenamen Dolphin entwickelte Nachfolger unter der Versionsnummer 7 erscheinen. Zeit, sich die Produktivitätsfeatures genauer anzuschauen.

Entwickelt hat das neue Java im Rahmen des OpenJDK eine Open-Source-Community, die die kompletten Sourcen in der von Sun mit Java 6 begonnenen Tradition unter der GNU General Public Licence (GPL) zur Verfügung stellt. Seit Anfang des Jahres ist die sogenannte Entwickler-Vorschau des OpenJDK 7 [1] funktional vollständig, und die Entwicklergemeinde ist seitdem aufgerufen, die letzten verbliebenen Fehler zu finden. Wenn der Plan klappt, steht die fertige Version ab 28. Juli zum Download bereit.

Mehr Infos

Was ist neu in Java 7?

Alle Artikel zur Reihe:

Die Java SE stellt die Basis-Plattform für Java-Anwendungen. Sie beschreibt nicht nur die Sprache Java, sondern auch deren Ausführungsumgebung (Java Virtual Maschine) und die Standard-APIs. Das alles geschieht unter dem Dach des Java Community Process (JCP). Der zu Java SE 7 gehörende JSR 336 [3] (Java Specification Request) entspricht einer Sammlung vieler weiterer (Teil-)Spezifikationen. Gemeinsam sind allen Teilen die Zielkategorien für die neuen Funktionen. Wie der Chief Platform Architect der Java-Plattform, Mark Reinhold, auf der JavaOne 2010 ankündigte, dreht sich alles um Performance, Allgemeingültigkeit, Integration und Produktivität. In diesem und drei weiteren Artikeln werden die neuen Funktionen von Java SE 7 nach diesen Kategorien vorgestellt.

Mark Reinhold auf der JavaOne 2010

In der Kategorie "Performance" sind zumeist Erweiterungen an bestehenden Bibliotheken zu finden. Dazu zählen der JSR 166y (Fork/Join), aber auch die im JSR 203 gesammelten "New I/O APIs" (NIO.2). In der Kategorie "Allgemeingültigkeit" sind hauptsächlich die Erweiterungen an der JVM gesammelt, zu nennen ist hier vor allem der JSR 292 (Supporting Dynamically Typed Languages on the Java Platform). Die mit "Integration" überschriebene Gruppe der Änderungen versammelt vor allem Aktualisierungen an bestehenden Standards, beispielsweise in den Bereichen Unicode oder Kryptographie.

Unter dem Begriff "Produktivität" finden sich die Spracherweiterungen, die dieser Artikel vorstellt. In der Kategorie ist das Ziel der Verbesserungen für Java klar formuliert. Auch wenn Java als Programmiersprache vergleichsweise einfach und schnell einzusetzen und zu erlernen ist, können viele Dinge noch einfacher werden und dafür sorgen, dass Entwickler mit weniger Code mehr schaffen. Das Ziel verfolgt Java SE 7 an vielen Stellen, den größten Beitrag aber leisten die im JSR 334 [4] zu findenden "Small Enhancements to the Java Programming Language", bekannt auch unter dem Namen Project Coin.

Eines der bemerkenswertesten Java-Projekte der vergangenen Jahre ist Project Coin. Es ist aus einer Sammlung von Ende Februar bis Ende März 2009 eingebrachten Vorschlägen für Verbesserungen an der Sprache Java hervorgegangen. Aus den knapp 70 Vorschlägen haben es sechs in die nächste Java-Version geschafft. An exponierter Stelle steht die Verwendung von Strings in Switch-Statements. Bisher ging das nur mit primitiven Daten-Typen, ihren Wrappern und Enums. Mit Java 7 lässt sich nun Folgendes realisieren:

  public static int getMonthNumber(String month) {
int monthNumber = 0;
if (month == null) { return monthNumber; }
switch (month.toLowerCase()) {
case "january": monthNumber = 1; break;
// ...
case "november": monthNumber = 11; break;
case "december": monthNumber = 12; break;
default: monthNumber = 0; break;
}
return monthNumber;
}

Das Beispiel vergleicht den String im Switch-Ausdruck via String.equals mit dem im case-Fall und gibt die entsprechende Nummer des Monats zurück. Das ist mit einigem Abstand die am meisten gewünschte Funktion der Entwickler. Ebenfalls neu ist die Möglichkeit, Literale mit einem Unterstrich ("_") zum Zweck der besseren Lesbarkeit zu formatieren. Zudem ist ein neuer Typ hinzugekommen. Es lassen sich nun auch binäre Literale verwenden.

1234_5678
1_2_3_4__5_6_7_8L
0b0001_0010_0100_1000

Nicht vorkommen darf der Unterstrich am Ende und am Anfang eines Literals sowie an zweideutigen Stellen, an denen die Interpretation gefährdet ist, etwa:

_1234
0x_1234
1234_

Am Exception Handling haben die Entwickler ebenfalls zwei lang erwartete Änderungen vorgenommen. Statt der leidigen Aneinanderreihung von Catch-Blöcken kann der Java-Programmierer jetzt mehrere Exceptions in einem Catch-Block fangen. Dabei steht jeweils ein OR-Symbol ("|") zwischen den Exception-Typen. Für alle Typen ist allerdings der gleiche Exception-Parameter zu verwenden.

try {
throwAorB();
} catch (ExceptionA | ExceptionB ex) {
throw ex;
}

Eine Verbesserung der Exception-Analyse zur Compilezeit wurde eingeführt. Das erneute Werfen einer Exception in einem catch Block (re-throw) erzeugt nun ein Objekt vom Typ der ursprünglich geworfenen Exception und nicht mehr vom Typ der gefangenen.

Zur weiteren Unterstützung der neuen Ansätze wurde eine Superklasse eingeführt. Die ReflectiveOperationException lässt sich als catch für ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException und NoSuchMethodException einsetzen.

Die mit Java 5 eingeführten Generics bekommen dank Coin ebenfalls eine kleine Politur, und zwar durch die Einführung des Diamond-Operators ("<...>"). Bisher waren Typen mehrfach redundant zu deklarieren.

Set<Person> persons = new HashSet<Person>();

Dank des Diamond-Operators ist die Deklaration des Sets jetzt einfacher.

Set<Person> persons = new HashSet<>();

Die kleine Änderung führt zu deutlich lesbareren Quellen und verhindert eine Menge Tipparbeit.

Das leidige Handling von Streams und Closable-Ressourcen vereinfacht das sogenannte Automatic Resource Management (ARM) deutlich. Waren bisher beispielsweise allerlei Arten von Streams (InputStream, OutputStream) in einem "try {} catch() {} finally {}"-Block zu schließen, gestaltet sich das mit dem neuen Interface AutoCloseable und den zugehörigen Änderungen im Rahmen der "try-with-resources"-Spezifikation einfach.

private static void close(Closeable closable) {
if (closable != null) {
try {
closable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Selbst der catch-Block ist optional. Erweiterungen an java.lang.Throwable schließen die Ressourcen nach dem try-Block automatisch und unterdrücken eventuell aufgetretene Exceptions. Es lassen sich eine oder mehrere Ressourcen gleichzeitig im try-Block deklarieren.

try (InputStream fis = new FileInputStream(source);
OutputStream fos = new FileOutputStream(target)){
// lesen und schreiben
} // Ressourcen automatisch geschlossen.

Eine Änderung an den Compiler-Warnungen beim Verwenden sogenannter Non-reifiable-Typen (E, List) in Varargs (variable Argumentenzahl an Methoden) erleichtert die Programmierung ebenfalls deutlich. Hat man bisher versucht, eine Varargs-Methode mit solchen Typen aufzurufen, erzeugt der Compiler die Warnung "unchecked". Diese wurde von der Seite des Aufrufers an die der relevanten Methodendeklaration verlagert. Bisher hat der Compiler immer eine "unsafe operation"-Warnung ausgegeben. Jetzt besteht zur Entwicklungszeit die Möglichkeit, mit @SuppressWarnings("varargs") diese zu unterdrücken. Mit der neuen @SafeVarargs-Annotation sind jetzt:

public static <T> List<T> java.util.Arrays.asList(T... a)
public static <T> boolean java.util.Collections.addAll
(Collection<? super T> c, T... elements)
public static <E extends Enum<E>> java.util.EnumSet<E>
EnumSet.of(E first, E... rest)
protected final void javax.swing.SwingWorker.publish(V... chunks)

versehen. Die Methoden sorgen dafür, dass keine Compiler-Warnungen mehr beim Verwenden von Varargs mit Collections ausgelöst werden.

Die Neuerungen erleichtern Java-Entwicklern ihre Arbeit. Leider bleiben größere Änderungen, die Sun eigentlich geplant hatte, noch in weiter Ferne. Nachdem Ende 2010 abzusehen war, dass Lambda-Ausdrücke, das die Java-Modularität angehende Jigsaw und noch weitere Vorschläge aus dem Project Coin nicht mehr für Java 7 fertig würden, beschloss [5] Oracle, die genannten größeren Änderungen mit dem JDK 8 auszuliefern, das für Ende 2012 geplant ist.

Das JDK 7 bleibt trotz gewachsenen Funktionsumfangs ein vergleichsweise kleines Intermezzo für Erweiterungen in der Kategorie Produktivität: Es vereinfacht vieles, und ein großer zusätzlicher Lernaufwand ist kaum zu erwarten. Viel mehr erwartet [6] den Java-Entwickler im JDK 8.

Markus Eisele [7]
ist Principle IT Architect bei der msg systems AG in München.






(ane [8])


URL dieses Artikels:
https://www.heise.de/-1274360

Links in diesem Artikel:
[1] http://openjdk.java.net/projects/jdk7/
[2] https://www.heise.de/hintergrund/Was-ist-neu-in-Java-7-Teil-2-Performance-1288272.html
[3] http://jcp.org/en/jsr/detail?id=336
[4] http://jcp.org/en/jsr/detail?id=334
[5] http://blogs.sun.com/mr/entry/plan_b
[6] http://blog.eisele.net/2010/09/java-se-7-8-9-road-ahead.html
[7] http://blog.eisele.net
[8] mailto:ane@heise.de