Java 9 Neue Funktionen

1. Übersicht

Java 9 verfügt über umfangreiche Funktionen. Obwohl es keine neuen Sprachkonzepte gibt, werden neue APIs und Diagnosebefehle für Entwickler auf jeden Fall interessant sein.

In diesem Artikel werden wir uns einige der neuen Funktionen kurz und allgemein ansehen. Eine vollständige Liste der neuen Funktionen finden Sie hier.

2. Modulares System - Puzzle-Projekt

Beginnen wir mit dem Großen - der Modularität der Java-Plattform.

Ein modulares System bietet ähnliche Funktionen wie das System des OSGi-Frameworks. Module haben ein Konzept von Abhängigkeiten, können eine öffentliche API exportieren und Implementierungsdetails verborgen / privat halten.

Eine der Hauptmotive hierbei ist die Bereitstellung einer modularen JVM, die auf Geräten mit viel weniger verfügbarem Speicher ausgeführt werden kann. Die JVM kann nur mit den Modulen und APIs ausgeführt werden, die von der Anwendung benötigt werden. Unter diesem Link finden Sie eine Beschreibung dieser Module.

Außerdem können interne JVM-APIs (Implementierungs-APIs) wie com.sun. * Nicht mehr über den Anwendungscode aufgerufen werden.

Einfach ausgedrückt, werden die Module in einer Datei namens module-info.java beschrieben, die sich oben in der Java-Code-Hierarchie befindet:

module com.baeldung.java9.modules.car { requires com.baeldung.java9.modules.engines; exports com.baeldung.java9.modules.car.handling; } 

Unser Modul Auto erfordert Modul Motor laufen zu lassen und die Exporte ein Paket zur Handhabung .

Weitere Informationen finden Sie in der OpenJDK Project Jigsaw: Modulsystem-Kurzanleitung.

3. Ein neuer HTTP-Client

Ein lang erwarteter Ersatz der alten HttpURLConnection .

Die neue API befindet sich unter dem Paket java.net.http .

Es sollte sowohl das HTTP / 2-Protokoll als auch den WebSocket-Handshake unterstützen und eine Leistung aufweisen, die mit der von Apache HttpClient, Netty und Jetty vergleichbar sein sollte.

Schauen Sie sich diese neue Funktionalität an, indem Sie eine einfache HTTP-Anfrage erstellen und senden.

Update: Der HTTP-Client-JEP wird in das Inkubator-Modul verschoben, sodass er im Paket java.net.http nicht mehr verfügbar ist und stattdessen unter jdk.incubator.http verfügbar ist.

3.1. Schnelle GET-Anfrage

Die API verwendet das Builder-Muster, was die schnelle Verwendung sehr einfach macht:

HttpRequest request = HttpRequest.newBuilder() .uri(new URI("//postman-echo.com/get")) .GET() .build(); HttpResponse response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandler.asString()); 

4. Prozess-API

Die Prozess-API wurde zur Steuerung und Verwaltung von Betriebssystemprozessen verbessert.

4.1. Prozessinformationen

Die Klasse java.lang.ProcessHandle enthält die meisten neuen Funktionen:

ProcessHandle self = ProcessHandle.current(); long PID = self.getPid(); ProcessHandle.Info procInfo = self.info(); Optional args = procInfo.arguments(); Optional cmd = procInfo.commandLine(); Optional startTime = procInfo.startInstant(); Optional cpuUsage = procInfo.totalCpuDuration();

Die aktuelle Methode gibt ein Objekt zurück, das einen Prozess darstellt, bei dem JVM derzeit ausgeführt wird. Die Unterklasse Info enthält Details zum Prozess.

4.2. Prozesse zerstören

Stoppen wir jetzt alle laufenden untergeordneten Prozesse mit destroy () :

childProc = ProcessHandle.current().children(); childProc.forEach(procHandle -> { assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy()); });

5. Kleine Sprachänderungen

5.1. Try-With-Resources

In Java 7 erfordert die Try-with-Resources- Syntax, dass für jede von der Anweisung verwaltete Ressource eine neue Variable deklariert wird.

In Java 9 gibt es eine zusätzliche Verfeinerung: Wenn die Ressource durch eine endgültige oder effektiv endgültige Variable referenziert wird, kann eine Try-with-Resources-Anweisung eine Ressource verwalten, ohne dass eine neue Variable deklariert wird:

MyAutoCloseable mac = new MyAutoCloseable(); try (mac) { // do some stuff with mac } try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) { // do some stuff with finalCloseable } catch (Exception ex) { } 

5.2. Diamond Operator Extension

Jetzt können wir den Diamantoperator in Verbindung mit anonymen inneren Klassen verwenden:

FooClass fc = new FooClass(1) { // anonymous inner class }; FooClass fc0 = new FooClass(1) { // anonymous inner class }; FooClass fc1 = new FooClass(1) { // anonymous inner class }; 

5.3. Private Methode der Schnittstelle

Schnittstellen in der kommenden JVM-Version können private Methoden haben, mit denen lange Standardmethoden aufgeteilt werden können:

interface InterfaceWithPrivateMethods { private static String staticPrivate() { return "static private"; } private String instancePrivate() { return "instance private"; } default void check() { String result = staticPrivate(); InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() { // anonymous class }; result = pvt.instancePrivate(); } }}

6. JShell Command Line Tool

JShell ist eine Read-Eval-Print-Schleife - kurz REPL.

Einfach ausgedrückt ist es ein interaktives Tool zum Auswerten von Deklarationen, Anweisungen und Ausdrücken von Java zusammen mit einer API. Es ist sehr praktisch, um kleine Codefragmente zu testen, für die ansonsten eine neue Klasse mit der Hauptmethode erstellt werden muss.

Die ausführbare Datei von jshell selbst befindet sich im Ordner / bin :

jdk-9\bin>jshell.exe | Welcome to JShell -- Version 9 | For an introduction type: /help intro jshell> "This is my long string. I want a part of it".substring(8,19); $5 ==> "my long string"

The interactive shell comes with history and auto-completion; it also provides functionality like saving to and loading from files, all or some of the written statements:

jshell> /save c:\develop\JShell_hello_world.txt jshell> /open c:\develop\JShell_hello_world.txt Hello JShell! 

Code snippets are executed upon file loading.

7. JCMD Sub-Commands

Let's explore some of the new subcommands in jcmd command line utility. We will get a list of all classes loaded in the JVM and their inheritance structure.

In the example below we can see the hierarchy of java.lang.Socket loaded in JVM running Eclipse Neon:

jdk-9\bin>jcmd 14056 VM.class_hierarchy -i -s java.net.Socket 14056: java.lang.Object/null |--java.net.Socket/null | implements java.io.Closeable/null (declared intf) | implements java.lang.AutoCloseable/null (inherited intf) | |--org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket | | implements java.lang.AutoCloseable/null (inherited intf) | | implements java.io.Closeable/null (inherited intf) | |--javax.net.ssl.SSLSocket/null | | implements java.lang.AutoCloseable/null (inherited intf) | | implements java.io.Closeable/null (inherited intf) 

The first parameter of jcmd command is the process id (PID) of the JVM on which we want to run the command.

Another interesting subcommand is set_vmflag. We can modify some JVM parameters online, without the need of restarting the JVM process and modifying its startup parameters.

You can find out all the available VM flags with subcommand jcmd 14056 VM.flags -all

8. Мulti-Resolution Image API

The interface java.awt.image.MultiResolutionImage encapsulates a set of images with different resolutions into a single object. We can retrieve a resolution-specific image variant based on a given DPI metric and set of image transformations or retrieve all of the variants in the image.

The java.awt.Graphics class gets variant from a multi-resolution image based on the current display DPI metric and any applied transformations.

The class java.awt.image.BaseMultiResolutionImage provides basic implementation:

BufferedImage[] resolutionVariants = .... MultiResolutionImage bmrImage = new BaseMultiResolutionImage(baseIndex, resolutionVariants); Image testRVImage = bmrImage.getResolutionVariant(16, 16); assertSame("Images should be the same", testRVImage, resolutionVariants[3]); 

9. Variable Handles

The API resides under java.lang.invoke and consists of VarHandle and MethodHandles. It provides equivalents of java.util.concurrent.atomic and sun.misc.Unsafe operations upon object fields and array elements with similar performance.

With Java 9 Modular system access to sun.misc.Unsafe will not be possible from application code.

10. Publish-Subscribe Framework

The class java.util.concurrent.Flow provides interfaces that support the Reactive Streams publish-subscribe framework. These interfaces support interoperability across a number of asynchronous systems running on JVMs.

We can use utility class SubmissionPublisher to create custom components.

11. Unified JVM Logging

This feature introduces a common logging system for all components of the JVM. It provides the infrastructure to do the logging, but it does not add the actual logging calls from all JVM components. It also does not add logging to Java code in the JDK.

The logging framework defines a set of tags – for example, gc, compiler, threads, etc. We can use the command line parameter -Xlog to turn on logging during startup.

Let's log messages tagged with ‘gc' tag using ‘debug' level to a file called ‘gc.txt' with no decorations:

java -Xlog:gc=debug:file=gc.txt:none ...

-Xlog:help will output possible options and examples. Logging configuration can be modified runtime using jcmd command. We are going to set GC logs to info and redirect them to a file – gc_logs:

jcmd 9615 VM.log output=gc_logs what=gc

12. New APIs

12.1. Immutable Set

java.util.Set.of() – creates an immutable set of a given elements. In Java 8 creating a Set of several elements would require several lines of code. Now we can do it as simple as:

Set strKeySet = Set.of("key1", "key2", "key3");

The Set returned by this method is JVM internal class: java.util.ImmutableCollections.SetN, which extends public java.util.AbstractSet. It is immutable – if we try to add or remove elements, an UnsupportedOperationException will be thrown.

You can also convert an entire array into a Set with the same method.

12.2. Optional to Stream

java.util.Optional.stream() gives us an easy way to you use the power of Streams on Optional elements:

List filteredList = listOfOptionals.stream() .flatMap(Optional::stream) .collect(Collectors.toList()); 

13. Conclusion

Java 9 wird mit einer modularen JVM und vielen anderen neuen und vielfältigen Verbesserungen und Funktionen geliefert.

Den Quellcode für die Beispiele finden Sie auf GitHub.