Nouvelles fonctionnalités de Java 9

1. Vue d'ensemble

Java 9 est livré avec un riche ensemble de fonctionnalités. Bien qu'il n'y ait pas de nouveaux concepts de langage, les nouvelles API et commandes de diagnostic seront certainement intéressantes pour les développeurs.

Dans cet article, nous allons avoir un aperçu rapide et de haut niveau de certaines des nouvelles fonctionnalités; une liste complète des nouvelles fonctionnalités est disponible ici.

2. Système modulaire - Projet Jigsaw

Commençons par le plus gros: apporter la modularité à la plate-forme Java.

Un système modulaire offre des capacités similaires à celles du système OSGi Framework. Les modules ont un concept de dépendances, peuvent exporter une API publique et garder les détails d'implémentation cachés / privés.

L'une des principales motivations ici est de fournir une JVM modulaire, qui peut fonctionner sur des périphériques avec beaucoup moins de mémoire disponible. La machine virtuelle Java peut fonctionner avec uniquement les modules et API requis par l'application. Consultez ce lien pour une description de ces modules.

De plus, les API internes (d'implémentation) de JVM telles que com.sun. * Ne sont plus accessibles à partir du code d'application.

En termes simples, les modules vont être décrits dans un fichier appelé module-info.java situé en haut de la hiérarchie du code java:

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

Notre voiture de module nécessite un moteur de module pour fonctionner et exporte un package pour la manipulation .

Pour un exemple plus détaillé, consultez OpenJDK Project Jigsaw: Module System Quick-Start Guide.

3. Un nouveau client HTTP

Un remplacement tant attendu de l'ancien HttpURLConnection .

La nouvelle API se trouve sous le package java.net.http .

Il doit prendre en charge à la fois le protocole HTTP / 2 et la négociation WebSocket, avec des performances comparables à celles d'Apache HttpClient, Netty et Jetty.

Jetons un œil à cette nouvelle fonctionnalité en créant et en envoyant une simple requête HTTP.

Mise à jour: Le JEP du client HTTP est déplacé vers le module Incubator, il n'est donc plus disponible dans le package java.net.http et est à la place disponible sous jdk.incubator.http.

3.1. Demande rapide GET

L'API utilise le modèle Builder, ce qui le rend vraiment facile pour une utilisation rapide:

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

4. API de processus

L'API de processus a été améliorée pour contrôler et gérer les processus du système d'exploitation.

4.1. Traitement de l'information

La classe java.lang.ProcessHandle contient la plupart des nouvelles fonctionnalités:

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();

La méthode actuelle renvoie un objet représentant un processus de JVM en cours d'exécution. La sous-classe Info fournit des détails sur le processus.

4.2. Détruire les processus

Maintenant - arrêtons tous les processus enfants en cours en utilisant destroy () :

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

5. Petites modifications linguistiques

5.1. Essayer avec des ressources

Dans Java 7, la syntaxe try-with-resources nécessite qu'une nouvelle variable soit déclarée pour chaque ressource gérée par l'instruction.

Dans Java 9, il y a un raffinement supplémentaire: si la ressource est référencée par une variable finale ou effectivement finale, une instruction try-with-resources peut gérer une ressource sans qu'une nouvelle variable ne soit déclarée:

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. Extension opérateur diamant

Nous pouvons maintenant utiliser l'opérateur diamant en conjonction avec des classes internes anonymes:

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. Méthode d'interface privée

Les interfaces de la prochaine version de JVM peuvent avoir des méthodes privées , qui peuvent être utilisées pour diviser de longues méthodes par défaut:

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. Outil de ligne de commande JShell

JShell est une boucle de lecture-évaluation-impression - REPL en abrégé.

En termes simples, il s'agit d'un outil interactif pour évaluer les déclarations, les instructions et les expressions de Java, avec une API. C'est très pratique pour tester de petits extraits de code, qui autrement nécessitent la création d'une nouvelle classe avec la méthode main .

L' exécutable jshell lui-même se trouve dans le dossier / 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 sera livré avec une JVM modulaire et de nombreuses autres améliorations et fonctionnalités nouvelles et diverses.

Vous pouvez trouver le code source des exemples sur GitHub.