Nouvelles fonctionnalités de Java 9

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 les 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 disponiblehere.

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 fonctionnalités similaires à celles du système OSGi. Les modules ont un concept de dépendances, peuvent exporter une API publique et garder les détails de l'implémentation cachés / privés.

L'une des principales motivations est de fournir une machine virtuelle Java modulaire, qui peut fonctionner sur des périphériques disposant de beaucoup moins de mémoire disponible. La machine virtuelle Java ne peut s'exécuter qu'avec les modules et les API requis par l'application. Consultezthis link pour une description de ce que sont ces modules.

De plus, les API internes (d'implémentation) de JVM telles quecom.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.example.java9.modules.car {
    requires com.example.java9.modules.engines;
    exports com.example.java9.modules.car.handling;
}

Notre modulecar nécessite le moduleengine pour s'exécuter et exporte un package pourhandling.

Pour un exemple plus détaillé, vérifiez OpenJDKProject Jigsaw: Module System Quick-Start Guide.

3. Un nouveau client HTTP

Un remplacement tant attendu des anciensHttpURLConnection.

La nouvelle API se trouve sous le packagejava.net.http.

Il doit prendre en charge à la fois la négociationHTTP/2 protocol etWebSocket, avec des performances comparables à celles desApache HttpClient,Netty etJetty.

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

Mise à jour: LeHTTP Client JEP est déplacé vers le module Incubator, il n'est donc plus disponible dans le packagejava.net.http et est à la place disponible sousjdk.incubator.http.

3.1. Demande rapide GET

L'API utilise le modèle Builder, ce qui facilite grandement l'utilisation rapide:

HttpRequest request = HttpRequest.newBuilder()
  .uri(new URI("https://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 le contrôle et la gestion des processus du système d'exploitation.

4.1. Traitement de l'information

La classejava.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éthodecurrent renvoie un objet représentant un processus de la JVM en cours d'exécution. La sous-classeInfo fournit des détails sur le processus.

4.2. Détruire les processus

Maintenant, arrêtons tous les processus enfants en cours d’exécution en utilisantdestroy():

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

5. Petites modifications du langage

5.1. Essayer avec des ressources

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

En Java 9, un raffinement supplémentaire est apporté: si la ressource est référencée par une variable finale ou une variable finale, une instruction try-with-resources peut gérer une ressource sans qu'une nouvelle variable 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 Diamond conjointement 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éthodesprivate, 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éthodemain.

L'exécutable dejshell lui-même se trouve dans le dossier<JAVA_HOME>/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"

Le shell interactif est livré avec l'historique et l'auto-complétion; il fournit également des fonctionnalités telles que l'enregistrement et le chargement à partir de fichiers, de tout ou partie des instructions écrites:

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

Les extraits de code sont exécutés lors du chargement du fichier.

7. Sous-commandes JCMD

Explorons quelques-unes des nouvelles sous-commandes de l'utilitaire de ligne de commandejcmd. Nous obtiendrons une liste de toutes les classes chargées dans la machine virtuelle Java et de leur structure d'héritage.

Dans l'exemple ci-dessous, nous pouvons voir la hiérarchie desjava.lang.Socket chargés dans JVM exécutant 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)

Le premier paramètre de la commandejcmd est l'ID de processus (PID) de la machine virtuelle Java sur laquelle nous voulons exécuter la commande.

Une autre sous-commande intéressante estset_vmflag. Nous pouvons modifier certains paramètres de machine virtuelle Java en ligne, sans qu'il soit nécessaire de redémarrer le processus de la machine virtuelle Java et de modifier ses paramètres de démarrage.

Vous pouvez trouver tous les indicateurs de VM disponibles avec la sous-commandejcmd 14056 VM.flags -all

8. API d'image multi-résolution

L'interfacejava.awt.image.MultiResolutionImage encapsule un ensemble d'images avec différentes résolutions dans un seul objet. Nous pouvons récupérer une variante d'image spécifique à la résolution basée sur une métrique DPI et un ensemble de transformations d'image donnés ou récupérer toutes les variantes de l'image.

La classejava.awt.Graphics obtient une variante à partir d'une image multi-résolution en fonction de la métrique DPI d'affichage actuelle et des transformations appliquées.

La classejava.awt.image.BaseMultiResolutionImage fournit une implémentation de base:

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

9. Poignées variables

L'API réside sousjava.lang.invoke et se compose deVarHandle etMethodHandles. Il fournit des équivalents d'opérationsjava.util.concurrent.atomic etsun.misc.Unsafe sur des champs objet et des éléments de tableau avec des performances similaires.

Avec Java 9 Modular, l'accès système àsun.misc.Unsafe ne sera pas possible à partir du code d'application.

10. Framework de publication-abonnement

La classejava.util.concurrent.Flow fournit des interfaces qui prennent en charge le cadre de publication-abonnementReactive Streams. Ces interfaces prennent en charge l’interopérabilité entre plusieurs systèmes asynchrones exécutés sur des machines virtuelles.

Nous pouvons utiliser la classe utilitaireSubmissionPublisher pour créer des composants personnalisés.

11. Journalisation JVM unifiée

Cette fonctionnalité introduit un système de journalisation commun pour tous les composants de la machine virtuelle Java. Il fournit l'infrastructure pour effectuer la journalisation, mais il n'ajoute pas les appels de journalisation réels de tous les composants de la machine virtuelle Java. Il n’ajoute pas non plus de journalisation au code Java dans le JDK.

Le cadre de journalisation définit un ensemble detags - par exemple,gc,compiler,threads, etc. Nous pouvons utiliser le paramètre de ligne de commande-Xlog pour activer la journalisation au démarrage.

Consignons les messages marqués avec la balise «gc» en utilisant le niveau «debug» dans un fichier appelé «gc.txt» sans décorations:

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

-Xlog:help affichera les options et exemples possibles. La configuration de la journalisation peut être modifiée à l'exécution à l'aide de la commandejcmd. Nous allons définir les journaux du GC sur info et les rediriger vers un fichier - gc_logs:

jcmd 9615 VM.log output=gc_logs what=gc

12. Nouvelles API

12.1. Ensemble immuable

java.util.Set.of() - crée un ensemble immuable d'éléments donnés. En Java 8, créer un ensemble de plusieurs éléments nécessiterait plusieurs lignes de code. Maintenant, nous pouvons le faire aussi simplement que:

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

LeSet renvoyé par cette méthode est la classe interne JVM:java.util.ImmutableCollections.SetN, qui étend publicjava.util.AbstractSet. C'est immuable - si nous essayons d'ajouter ou de supprimer des éléments, unUnsupportedOperationException sera lancé.

Vous pouvez également convertir un tableau entier en unSet avec la même méthode.

12.2. Facultatif pour diffuser

java.util.Optional.stream() nous donne un moyen simple d'utiliser la puissance des flux sur des éléments optionnels:

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

13. Conclusion

Java 9 sera livré avec une machine virtuelle Java modulaire et de nombreuses autres améliorations et fonctionnalités nouvelles et variées.

Vous pouvez trouver le code source des exemplesover on GitHub.