Tutoriel pour découvrir les nouveautés de Java 15

java beans

Vous trouverez dans ce tutoriel une découverte des nouveautés de Java 15 avec des explications et des exemples. Pour réagir au contenu de cet article, un espace de dialogue vous est proposé sur le forum 3 commentaires Donner une note  l'article (5)

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Introduction

Java 15 est sortie! Elle est disponible depuis 15/09. Nous proposons dans cet article une présentation des principales améliorations apportées par le langage Java.

Aperçu

Une fonctionnalité d’aperçu est une fonctionnalité qui est conçue, spécifiée et implémentée mais non permanente.

Incubateur (incubator)

Une fonction d’incubateur est expérimentale sous le package jdk.incubator pour permettre aux utilisateurs de fournir leurs commentaires.

Deuxième aperçu

Deuxième aperçu signifie que la fonctionnalité:

  • était en aperçu à la version précédente
  • incorpore quelques améliorations
  • réaperçu pour obtenir plus de retours des utilisateurs.

2. Aperçus (Preview)/ incubateur (incubator)

2.1. Classes scellées (Sealed classes) (Aperçu)

Une classe scellée est une classe spécifique qui ne peut pas s'étendre (extends) ou être implémentée (implements) sauf

  • Si c'est déclaré explicitement en utilisant le mot clé sealed au niveau de la classe
  • En utilisant le mot clé permits pour les classes autorisées

JDK 15 améliore le langage de programmation Java avec des classes et des interfaces scellées. Les classes et interfaces scellées limitent les autres classes ou interfaces qui peuvent les étendre ou les implémenter. L'extension ou l'implémentation doit être partielle et pas totale. Elle est partielle via l'utilisation du mot clé permits qui donne un sous-ensemble de classe ou d'interface autorisé à enrichir la définition initiale.

Dans l’exemple ci-dessous, nous déclarons que la forme de classe autorise trois sous-classes spécifiques :

 
Sélectionnez
package com.example.geometry;
public sealed class Shape
permits Circle, Rectangle, Square {...}

2.2. Correspondance de motifs (Pattern matching) par instanceof (Deuxième aperçu)

JDK 15 améliore le langage de programmation Java avec l’appariement des motifs pour l’opérateur instanceof. La correspondance des motifs permet d’exprimer une logique commune dans un programme, à savoir l’extraction conditionnelle de composants à partir d’objets, de manière plus concise et sécuritaire. Il s’agit d'une fonctionnalité d’aperçu dans JDK 15.

Le but de cette fonctionnalité est de se débarrasser du code répétitif et standard

Souvent, nous devons faire quelque chose de similaire à l'exemple dessous :

 
Sélectionnez
if (obj instanceof Integer) {
    Integer i = (Integer) obj;
    //faire quelque chose avec i en tant que Integer
} else {
    Object obj = obj;
    //faire quelque chose avec obj en tant qu'Objet
}

Cela est sujet à des erreurs et un peu répétitif. Il y a des plusieurs déclarations de Integer ici. À partir de JDK 15, avec cette fonctionnalité, nous pouvons faire le suivant:

 
Sélectionnez
if (obj instanceof Integer i) {
    // faire quelque chose avec i
} else {
    // impossibilité de faire quelque chose avec i ici
}

Les travaux futurs sur ce JEP (JDK enhancement proposal/JDK proposition d'amélioration) incluront la même logique pour d’autres instructions comme l’instruction de switch.

fonctionnalité d’aperçu

JEP

2.3. Enregistrements (Records) (Deuxième aperçu)

2.3.1. Situation avant cette fonctionnalité

 
Sélectionnez
final class Person {
    public final String firstname;
    public final String lastname;

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }
    // ici on doit implementer equals, hashCode, toString
    // il s'agit du code répétitif et standard }

La méthode de getters and setters est beaucoup utilisée en Java. Elle applique le principe d'encapsulation, une principe de base dans la programmation orientée objet.

Même si ce principe est beaucoup utilisé, elle est une méthode du code répétitif qui fait perdre du temps au développeur. Ce code est si répétitif que des outils comme Intellij ou Eclipse offrent la génération automatique de ce code-là.

2.3.2. Lombok: une bibliothèque utile

Lombok est une bibliothèque qui résout le problème décrit dessus. En utilisant Lombok, on peut éviter du code répétitif. Regardons un exemple :

 
Sélectionnez
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor(access = AccessLevel.PUBLIC)
    public class Person {
    public final String firstname;
    public final String lastname;
  }

L'inconvénient est que Lombok est une bibliothèque externe. On est obligé d'obtenir la dépendance.

2.3.3. La nouvelle solution

Les enregistrements (records) sont des classes qui agissent comme des porteurs transparents pour les données immuables. Les enregistrements peuvent être considérés comme des tuples nominaux.

Le but de la fonctionnalité enregistrements est d'offrir une syntaxe plus compacte et claire comme décrit ci-dessous :

 
Sélectionnez
record Person(String firstname, String lastname) { }

Avec cette fonctionnalité on peut écrire plus facilement un POJO (Plain Old Java Object) en utilisant un record.

On n'a plus besoin d'implémenter les méthodes de base equals() et hashCode().

La fonctionnalité records peut éventuellement remplacer la bibliothèque Lombok.

2.4. API d’accès à la mémoire externe (deuxième incubateur)

L'API d'accès à la mémoire externe (Foreign memory access API) permet aux programmes Java d’accéder de manière sûre et efficace à la mémoire externe en dehors du Java heap. Le but principal est d'éviter le coût et l'imprévisibilité liée au garbage collection (spécialement quand il y a de larges caches). Cette fonctionnalité ressemble à la fonction malloc du langage C où on peut demander l'allocation de la mémoire.

Un autre objectif est de partager la mémoire dans des processus multiples. Cette fonctionnalité intègre trois abstractions:

  • MemorySegment est une région de mémoire contiguë ;
  • MemoryAddress modélise une adresse ;
  • MemoryLayout est une description du contenu d'un segment.

Voici un exemple d'un MemorySegment associé à buffer de mémoire de 100 octets:

 
Sélectionnez
try (MemorySegment segment = MemorySegment.allocateNative(100)) {
...
  }

3. Fonctionnalités indépendantes

3.1. Algorithme de signature numérique Edwards-Curve (EdDSA)

Dans la cryptographie à clé publique, Edwards-Curve Digital Signature Algorithm est un schéma mathématique pour vérifier l’authenticité des messages numériques.

Cette fonctionnalité implémente des signatures cryptographiques à l’aide de l’algorithme de signature numérique Edwards-Curve (EdDSA) tel que décrit par RFC 8032.

EdDSA est demandé grâce à sa sécurité et sa performance améliorée. EdDSA est utilisé dans d'autres bibliothèques crypto comme OpenSSL et BoringSSL.

 
Sélectionnez
//exemple : générer une paire de clés et signer
KeyPairGenerator kpg = KeyPairGenerator.getInstance(« Ed25519 »);
KeyPair kp = kpg.generateKeyPair();
// algorithme est Ed25519
Signature sig = Signature.getInstance(« Ed25519 »);
sig.initSign(kp.getPrivate());
sig.update(msg);
byte[] s = sig.sign();

// example: utiliser KeyFactory pour construire une clé publique
KeyFactory kf = KeyFactory.getInstance("EdDSA");
boolean xOdd = ...
BigInteger y = ...
NamedParameterSpec paramSpec = new NamedParameterSpec("Ed25519");
EdECPublicKeySpec pubSpec = new EdECPublicKeySpec(paramSpec, new EdPoint(xOdd, y));
PublicKey pubKey = kf.generatePublic(pubSpec);

RFC 8032

3.2. Classes cachées (Hidden Classes)

Les classes cachées sont des classes qui ne peuvent pas être utilisées directement par le bytecode d’autres classes. Les classes cachées sont destinées à être utilisées par des frameworks qui génèrent des classes au moment de l’exécution et les utilisent indirectement, via la réflexion. Une classe cachée peut être définie comme un membre d’un nid de contrôle d’accès (Nest-Based Access Control) et peut être déchargée indépendamment des autres classes.

La différence la plus importante est dans la création d'une classe cachée. Pour créer une classe normale on invoque ClassLoader::defineClass. Par contre une classe cachée est créée par l'invocation du Lookup::defineHiddenClass. Ça provoque le JVM à dériver la classe cachée depuis les octets fournis, lier la classe cachée, et retourner un objet lookup qui fournit l'accès via la réflexion à la classe cachée.

Nid de contrôle d’accès (Nest-Based Access Control)

3.3. Blocs de texte

Ce JDK ajoute des blocs de texte au langage Java. Un bloc de texte est un littéral de chaîne multiligne qui évite la nécessité de la plupart des séquences d’échappement, formate automatiquement la chaîne d’une manière prévisible et donne au développeur le contrôle sur le format lorsque vous le souhaitez.

En Java, le fait d'embarquer un snippet de HTML, SQL, XML ou JSON dans un littéral de chaîne de caractères nécessite souvent une édition significative avec de caractères d'échappement et concaténation pour qu'il puisse être compilé.

Les blocs de texte offrent une approche plus simple à ce problème décrit ci-dessous :

 
Sélectionnez
En utilisant un string "une-dimension"

String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Bonjour les amis de developpez.net!</p>\n" +
              "    </body>\n" +
              "</html>\n";
En utilisant un bloc de text "deux-dimensions"

String html = """
              <html>
                  <body>
                      <p>Bonjour les amis de developpez.net!</p>
                  </body>
              </html>
              """;

4. Deprecated - Ré-développement

4.1. Suppression le moteur JavaScript Nashorn

Le moteur de script Nashorn JavaScript et les API, ainsi que l ’outil jjs sont supprimés. Le moteur, les API et l’outil ont été déconseillés (deprecated) pour être retirés en Java 11 avec l’intention de les supprimer dans une version ultérieure. La raison en était que l’équipe considérait qu’il était difficile de les maintenir.

4.2. Supprimer les ports Solaris et SPARC

Suppression du code source et du support de compilation des ports Solaris/SPARC, Solaris/x64 et Linux/SPARC. Ces ports ont été depreciés pour suppression dans JDK 14 avec l’intention expresse de les supprimer dans une future version.

4.3. Activation RMI devient deprecated

Déprécier le mécanisme d’activation RMI pour la suppression future. RMI Activation est une partie obsolète de RMI qui est facultative depuis Java 8. Aucune autre partie du RMI ne sera dépréciée.

Mécanisme d’activation RMI

4.4. Réimplémentation de l’API Legacy DatagramSocket

Cette fonctionnalité remplace les anciennes implémentations des API

  • java.net.DatagramSocket
  • java.net.MulticastSocket

par des implémentations plus simples et plus modernes qui sont faciles à maintenir et à déboguer. Les nouvelles implémentations seront faciles à adapter.

4.5. Désactiver et déprécier le verrouillage biaisé

Cette fonctionnalité désactive le verrouillage biaisé (biased locking) par défaut et déprécie toutes les options de ligne de commande associées.

Le verrouillage biaisé est utilisé si les objets ne sont verrouillés que par un thread. Dans ce cas-là, la JVM peut effectuer une optimisation et « biaiser » cet objet vers ce thread de telle sorte que les opérations atomiques ultérieures sur l'objet n'entraînent aucun coût de synchronisation.

Les gains de performance observés dans le passé sont beaucoup moins évidents aujourd’hui. Ce fait combiné à la difficulté de le maintenir a conduit à cette décision de désactivation et dépréciation du verrouillage biaisé.

5. Deux nouveaux Garbage Collectors

Le Garbage Collector (GC) est un gestionnaire de mémoire automatique qui libère la mémoire en supprimant les objets qui ne sont plus nécessaires.

5.1. ZGC : un collecteur d’ordures évolutif à faible latence

Le projet ZGC a réellement commencé avec Java 11. Il s’agit d’un sujet complexe qui devait être introduit progressivement pour permettre aux utilisateurs de fournir leurs commentaires et d’avoir des bogues corrigés. En Java 15, cette fonctionnalité est considérée comme complète et prête à être utilisée en mode production.

ZGC peut être activé à l’aide des options de ligne de commande -XX:+UnlockExperimentalVMOptions -XX:+UseZGC.

Cette fonctionnalité offre ce collecteur d’ordures maintenant, mais ne change pas la valeur par défaut qui resteG1.

5.2. Shenandoah : un collecteur d’ordures à faible pause-temps

Semblable à ZGC ici Shenandoah est un éboueur qui est prêt pour l'environnement de production. Il a été introduit comme expérimental en Java 12.

Il peut être activé avec xx:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC. Cette fonctionnalité conserve le collecteur d’ordures G1 par défaut.

6. Conclusion

Java 15 a plusieurs nouvelles fonctionnalités à offrir, comme chaque version. Cette version ajoute plus de valeur à java en raison de :

  • suppression ou mise en place comme obsolète des anciennes bibliothèques et leur remplacement par des bibliothèques modernes ;
  • deux nouveaux garbage collectors ;
  • nouvelles fonctionnalités utiles (classes cachées, blocs de texte, enregistrements).

Il est toujours utile de mettre à jour la version.

La version originale en version anglaise de cet article est disponible sur mon blog à cette adresse strong-programmer.com

7. Aller plus loin

Plus de détails sur les nouveautés de Java 15 : JDK 15.

En savoir plus sur la fonctionnalité d'aperçu : aperçu.

Téléchargement d'une version : ici.

Site officiel de OpenJDK : https://openjdk.java.net/.

8. Remerciements

Mickaël pour son aide inestimable sur la qualité globale de l'article : https://mbaron.developpez.com/

Claude pour la relecture : https://claudeleloup.developpez.com/.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2020 Thanos Floros. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.