Herzlich willkommen zum DevDay 2017 Neuerungen der Java SE 9 Dominic A. Merz Fachbereichsleiter Java, Web und Mobile Technologies
Agenda n Einführung des Module System n Anpassung der Sprache n Erweiterung der API n JVM Features n Verbesserung der Performance 2
Module System: Überblick n Projekt Jigsaw (seit 2008!) n Modul wie JAR, aber: n mit einem Namen n mit definierten Abhängigkeiten n mit Kapselung n ohne Versionierung n Java SE / JDK auch in Module aufgeteilt (cf. Module Graphs) n kein neues Format 3
Module System: Module Descriptor n Datei mit Namen module-info.java n Beispiel: module java.sql { requires transitive java.logging; requires transitive java.xml; uses java.sql.driver; exports java.sql; exports javax.sql; exports javax.transaction.xa; n keine neuen Schlüsselwörter (wie requires, exports, uses, transitive u.a.) 4
Module System: Feature "Reliable Configuration" n alle requires Module unbedingt vorhanden n keine Mehrdeutigkeiten n keine Abhängigkeitszyklen n kein Paket gleichzeitig in mehreren Modulen 5
Module System: Feature "Strong Encapsulation" n Kapselung mit exports n Konsequenz: neue Definition von public n Der Typ ist public. n Das Modul exportiert das entsprechende Paket. n Ihr Modul benötigt das entsprechende Modul. 6
Module System: Feature "Service Registry" n alle requires Module müssen vorhanden sein n Beispiel: module mysql.driver { requires java.sql; provides java.sql.driver with com.mysql.mysqldriver; n Laden mit: List<Driver> drivers = new ArrayList<>(); ServiceLoader.load(Driver.class).forEach(drivers::add); 7
Module System: weitere Features n Tuning Features n feingranulare Abhängigkeiten: "Optional Dependencies" n feingranulare Kapselung: "Qualified Exports" n namenlose oder automatische Module: für schrittweise Migration n Module in Layers: für Container n Runtime Images: mit jlink (neues Linker Tool) 8
Sprachanpassungen: private Methoden in Schnittstellen n Beispiel: public interface Calculator { default boolean isevensum(int... values) { return sum(values) % 2 == 0; default boolean isoddsum(int... values) { return sum(values) % 2 == 1; private int sum(int[] numbers) { return IntStream.of(numbers).sum(); 9
Sprachanpassungen: private Methoden in Schnittstellen n für gemeinsamen Code innerhalb der Schnittstelle n wie private Methoden in abstract Klassen n müssen implementiert sein n sind nur in der Schnittstelle sichtbar n können nicht überschrieben werden 10
Sprachanpassungen: try-with-resources n Beispiel: public void method(connection connection) throws Exception { try (connection) { connection.use(); n bisherige Zuweisung an eine lokale, implizit final deklarierte Variable fällt weg n Nutzung des neuen Konzepts aus Java SE 8: "effectively final" n Compiler verhindert immer noch eine neue Zuweisung 11
Sprachanpassungen: Diamond-Operator n Beispiel: List<String> list = new ArrayList<>() {; n Typparameter kann auch bei anonymen Klassen inferiert werden 12
Sprachanpassungen: @SafeVarargs n Heap Polution: private <T> T[] replace(t value, T... values) { /* replace null in values with value */ return values; private <T> T[] replace(t value, T first, T second) { return replace(value, first, second); n kein Array von Typparametern möglich: Rückgabewert der ersten Methode ist Object[] n Compiler warnt auch bei sicheren Fällen n Annotation @SafeVarargs verhindert Warnung: nur bei final deklarierten Methoden möglich 13
Sprachanpassungen: @SafeVarargs n Beispiel: @SafeVarargs private <T> Optional<T> firstnonnull(t... values) { return Arrays.stream(values).filter(Objects::nonNull).findFirst(); n Annotation auch bei private deklarierten Methoden anwendbar 14
Sprachanpassungen: @Deprecated n Beispiel: import java.io.linenumberinputstream; @Deprecated public class Deprecation { private LineNumberInputStream() in; n bei mit @Deprecated annotierten Typen keine Warnung aufgrund des Imports mehr 15
API: Collection Factories n Deklarative Liste: List<String> list = [ "one", "two", "three" ]; Wäre das nicht toll?! n Deklarative Abbildung: Map<String, Integer> map = [ "one" = 1, "two" = 2, "three" = 3 ]; Wäre das nicht cool?! n IT'S NOT GONNA HAPPEN! Hmm... 16
API: Collection Factories n Gründe: n Änderung an der Sprache sehr kostspielig n Sprache an das Collection Framework gebunden n spezifische Typen werden bevorzugt n Lösung: einfache Fabrikmethoden 17
API: Collection Factories n Beispiel für Liste: List<String> list = List.of("one", "two", "three"); n Beispiel für Menge: Set<String> set = Set.of("one", "two", "three"); n Beispiel für Abbildung: Map<String, Integer> map = Map.of("one", 1, "two", 2, "three", 3); n Beispiel für Abbildung (mit Tupeln): Map<String, Integer> map = Map.ofEntries( entry("one", 1), entry("two", 2), entry("three", 3)); 18
API: Collection Factories n Achtung: n unveränderbar (sog. immutable) n keine null-werte n zufällige Iterationsreihenfolge von einer Ausführung zur nächsten 19
API: Reactive Streams n beteiligte Akteure n Producer: n produziert Items n nimmt Anmeldungen der Subscriber entgegen n Subscriber: n meldet sich beim Producer an n implementiert die Methoden onnext(), onerror() und oncomplete() n Subscription n stellt die Verbindung zwischen Producer und Subscriber dar n implementiert die Methoden request() und cancel() 20
API: Reactive Streams n Ablauf "Subscribing" n Publisher pub wird erzeugt n Subscriber sub wird erzeugt n werden mit Aufruf pub.subscribe(sub) verhängt n Publisher erzeugt Subscription script n Publisher ruft sub.onsubscription(script) auf n Subscriber kann sich die Subscription merken 21
API: Reactive Streams n Ablauf "Streaming" n Subscriber ruft script.request(10) auf n Publisher ruft sub.onnext(item) auf [max. 10mal] n Ablauf "Canceling" n Publisher kann sub.onerror() oder sub.oncomplete() aufrufen n Subscriber kann script.cancel() aufrufen n bisher (d.h. Java SE 9) n nur Schnittstellen definiert n noch nicht im JDK genutzt 22
JVM: Multi-Release JAR n Beispiel: n Code für Java SE 8 public class Version { public String get() { return "Java SE 8"; n Code für Java SE 9 public class Version { public String get() { return "Java SE 9"; 23
JVM: Multi-Release JAR n gemeinsamer Code public class Main { public static void main(string[] args) { System.out.println(new Version().get()); n Kompilation der Java-Dateien: n Klasse Main und Klasse Version für Java SE 8 --> Verzeichnis bin/java8 n Klasse Version für Java SE 9 --> Verzeichnis bin/java9 24
JVM: Multi-Release JAR n "Multi-Release JAR"-Datei erzeugen n neue Kommandozeilenoption: --release n Beispiel für Aufruf: jar --create --file dist/multirelease.jar -C bin/java8. --release 9 -C bin/java9. 25
JVM: Multi-Release JAR n Verzeichnisstruktur in der "Multi-Release JAR"-Datei: - org - company - Main.class - Version.class - META-INF - versions - 9 - org - company - Version.class 26
JVM: Multi-Release JAR n Aufruf zum Programmstart java jar dist/multirelease.jar org.company.main n Output (mit JRE, Version 8): > Java SE 8 n Output (mit JRE, Version 9): > Java SE 9 27
JVM: weitere Features n neuer Version-String javac version > javac 9.0.1 java version > java version "9.0.1" n neue und ergänzte Kommandozeilen-Optionen im GNU-Stil: cp -classpath --class-path 28
Performance: java.lang.string im Memory n Werttyp char: 2 Byte (UTF-16 Code Unit) n in Texten meist nur ISO-8859-1: 1 Byte (ASCII / EBCDIC) n Referenztyp java.lang.string intern: char[] -> byte[] n Benchmark-Test (von Aleksey Shipilëv): 1.4mal mehr Durchsatz 1.85mal weiniger Garbage 29