IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

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

java beans

Vous trouverez dans ce tutoriel une découverte des nouveautés de Java 16 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 16 est toujours en phase de développement. La disponibilité générale sera en 16/03/2021. 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. Vector API (incubateur)

JDK 16 fournit une itération initiale d'un module d'incubateur, jdk.incubator.vector, pour exprimer des calculs vectoriels qui compilent de manière fiable au moment de l'exécution des instructions matérielles (hardware) vectorielles optimales sur les architectures de processeur prises en charge et obtiennent ainsi des performances supérieures aux calculs scalaires équivalents.

Voici un exemple d'une computation "scalar" sur des elements de arrays

 
Sélectionnez
void scalarComputation(float[] a, float[] b, float[] c) {
   for (int i = 0; i < a.length; i++) {
        c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f;
   } //(We assume that the array arguments will be of the same size.)
}

Une manière explicite d'implémenter le calcul vectoriel équivalent à l'aide de l'API Vector est la suivante:

 
Sélectionnez
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_256;

void vectorComputation(float[] a, float[] b, float[] c) {

    for (int i = 0; i < a.length; i += SPECIES.length()) {
        var m = SPECIES.indexInRange(i, a.length);
		// FloatVector va, vb, vc;
        var va = FloatVector.fromArray(SPECIES, a, i, m);
        var vb = FloatVector.fromArray(SPECIES, b, i, m);
        var vc = va.mul(va).
                    add(vb.mul(vb)).
                    neg();
        vc.intoArray(c, i, m);
    }
}
}

3. Activer fonctionnalités du langage C++14

Autoriser l'utilisation des fonctionnalités du langage C ++ 14 dans le code source JDK C ++ et donnez des conseils spécifiques sur les fonctionnalités qui peuvent être utilisées dans le code HotSpot.

Permis:

  1. constexpr
  2. Sized deallocation
  3. Variadic templates
  4. Static assertions
  5. decltype
  6. Right angle brackets (n1757) — Eliminates an annoying syntactic wart.
  7. Default template arguments for function templates
  8. Template aliases
  9. Strongly-typed enums
  10. Delegating constructors

Pour la liste entiere regardez le C++14 Language Features

4. Migrer de Mercurial à Git

Migration des référentiels de code source de la communauté OpenJDK de Mercurial (hg) vers Git.

Buts

  • Migrez tous les projets OpenJDK à référentiel unique de Mercurial vers Git
  • Conserver tout l'historique du contrôle de version, y compris les balises
  • Reformater les messages de commit selon les meilleures pratiques de Git
  • Portez les outils jcheck, webrev et defpath vers Git
  • Créer un outil pour traduire entre les hachages Mercurial et Git

Il existe trois raisons principales pour migrer vers Git:

  • Taille des métadonnées du système de contrôle de version
  • Outillage disponible
  • Hébergement disponible

Pour plus de détails regardez ici:JEP 357

5. Migrer à Github

Hébergement des référentiels Git de la communauté OpenJDK sur GitHub. En combinaison avec JEP 357 (Migrer de Mercurial vers Git), cela migrerait tous les projets OpenJDK à référentiel unique vers GitHub, y compris les versions de fonctionnalités JDK et les versions de mise à jour JDK pour les versions 11 et ultérieures.

Objectifs

  • Hébergement tous les référentiels OpenJDK Git sur https://github.com/openjdk/.
  • Exécution des vérifications de pré-validation (jcheck) avant chaque push.
  • Intégration des services OpenJDK existants.
  • Activation de plusieurs façons d'interagir avec GitHub.

Metrics

  • Temps de clonage et d'extraction nettement plus rapides
  • Meilleure disponibilité (temps de fonctionnement) des référentiels
  • Possibilité d'interagir avec les référentiels sur GitHub via les listes de diffusion OpenJDK
  • Possibilité d'interagir avec les référentiels sur GitHub via des outils de ligne de commande
  • Possibilité d'interagir avec les référentiels sur GitHub via les navigateurs Web

Github a été selectionné parce qu'il est exceptionnel sur les trois raisons primotdials de selection d'un fournisseur externe. Les performances de GitHub sont aussi bonnes ou supérieures à celles d'autres fournisseurs, il s'agit du plus grand service d'hébergement de code source au monde (50 millions d'utilisateurs en mai 2020), et il possède l'une des API les plus complètes.

Pour plus de détails regardez ici:JEP 369

6. ZGC: Traitement simultané de la pile de threads

Déplacement du traitement de pile de threads ZGC (Z Garbage Collector) des points de restauration vers une phase simultanée.

  • Supprimez le traitement de pile de threads des points de sécurité ZGC.
  • Rendre le traitement de pile paresseux, coopératif, simultané et incrémental.
  • Supprimez tous les autres traitements de racine par thread des points de restauration ZGC.
  • Possibilité d'interagir avec les référentiels sur GitHub via des outils de ligne de commande
  • Fournit un mécanisme par lequel les autres sous-systèmes HotSpot peuvent traiter paresseusement les piles.

7. Unix-Domain Socket Channels

Les sockets du domaine Unix sont utilisés pour la communication inter-processus (IPC) sur le même hôte. Ils sont similaires aux sockets TCP / IP à bien des égards, sauf qu'ils sont adressés par des noms de chemin de système de fichiers plutôt que par des adresses IP (Internet Protocol) et des numéros de port. L'objectif de ce JEP est de prendre en charge toutes les fonctionnalités des sockets de domaine Unix qui sont communes aux principales plates-formes Unix et Windows. Les canaux de socket du domaine Unix se comportent de la même manière que les canaux TCP / IP existants en termes de comportement de lecture / écriture, de configuration de la connexion, d'acceptation des connexions entrantes par les serveurs, de multiplexage avec d'autres canaux sélectionnables non bloquants dans un sélecteur et de prise en charge du socket approprié options.

Pour la communication locale entre processus, les sockets du domaine Unix sont à la fois plus sécurisées et plus efficaces que les connexions de bouclage TCP / IP. Le server-socket channel API se trouve dans le package java.nio.channels

8. Alpine linux port

L'objectif est de porter le JDK sur Alpine Linux et sur d'autres distributions Linux qui utilisent musl comme bibliothèque C principale, sur les architectures x64 et AArch64,

Motivation Musl est une implémentation, pour les systèmes basés sur Linux, de la fonctionnalité de bibliothèque standard décrite dans les normes ISO C et POSIX. Plusieurs distributions Linux, notamment Alpine Linux et OpenWrt, sont basées sur musl, tandis que d'autres fournissent un package musl facultatif (par exemple, Arch Linux).

La distribution Alpine Linux est largement adoptée dans les déploiements cloud, les microservices et les environnements de conteneurs en raison de sa petite taille d'image. Une image de base Docker pour Alpine Linux, par exemple, fait moins de 6 Mo. Permettre à Java de s'exécuter directement dans de tels paramètres permettra à Tomcat, Jetty, Spring et d'autres frameworks populaires de fonctionner de manière native dans ces environnements. Ce JEP entend intégrer le projet Portola en amont.

Pour créer une variante musl du JDK sous Alpine Linux, les packages suivants sont requis:

alpine-sdk alsa-lib alsa-lib-dev autoconf bash tasses-dev tasses-libs fontconfig fontconfig-dev freetype freetype-dev grep libx11 libx11-dev libxext libxext-dev libxrandr libxrandr-dev libxrender libxrender-dev libxt libxt-dev libxtstxtst -dev linux-headers zip

Une fois ces packages installés, le processus de construction JDK fonctionne comme d'habitude.

Alpine Linux.

Musl.

9. Elastic Metaspace

Le but de cette fonctionnalité est de renvoyer plus rapidement la mémoire de métadonnées de classe HotSpot inutilisée (c'est-à-dire métaspace) au système d'exploitation, réduire l'empreinte de méta-espace, et simplifiez le code de méta-espace afin de réduire les coûts de maintenance.

Depuis sa création dans JEP 122, metaspace a été quelque peu connu pour son utilisation élevée de la mémoire hors heap. La plupart des applications normales n'ont pas de problèmes, mais il est facile de "embêter" l'allocateur de méta-espace dans le mauvais sens pour provoquer un gaspillage de mémoire excessif. Malheureusement, ces types de cas ne sont pas rares. Nous proposons de remplacer l'allocateur de mémoire metaspace existant par un schéma d'allocation basé sur les copains(Buddy memory allocation). Il s'agit d'un algorithme ancien et éprouvé qui a été utilisé avec succès, par exemple, dans le noyau Linux. Ce schéma rendra pratique l'allocation de la mémoire de méta-espace par petits morceaux, ce qui réduira la surcharge du chargeur de classe. Cela réduira également la fragmentation, ce qui nous permettra d'améliorer l'élasticité en renvoyant la mémoire de méta-espace inutilisée au système d'exploitation.

bussy memory allocation.

10. Windows/AArch64 Port

Avec l'arrivé de AArch64(ARM64), Windows/AArch64Cette est devenue une plate-forme importante en raison de la demande des utilisateurs finaux.. Cette fonctionnalité amene le JDK à Windows/AArch64.

JDK 16 introduit est intriduit sur Windows / AArch64, en étendant le travail effectué précédemment pour le port Linux / AArch64 (JEP 237). Ce port inclut l'interpréteur de modèle, les compilateurs JIT C1 et C2 et les garbage collector (série, parallèle, G1, Z et Shenandoah). Il prend en charge les systèmes d'exploitation Windows 10 et Windows Server 2016.

AArch64

11. Foreign Linker API (Incubator)

Foreign Linker est une API qui offre un accès purement Java de type statique au code natif. Cette API, associée à l'API de mémoire étrangère (JEP 393), simplifiera considérablement le processus de liaison à une bibliothèque native, par ailleurs sujet aux erreurs.

Buts

  • Facilité d'utilisation: remplacez JNI par un modèle de développement purement Java supérieur.
  • Support C: La portée initiale de cet effort vise à fournir une interopérabilité de haute qualité, entièrement optimisée avec les bibliothèques C, sur les plates-formes x64 et AArch64.
  • Généralités: L'API et l'implémentation de Foreign Linker doivent être suffisamment flexibles pour, au fil du temps, prendre en charge d'autres plates-formes (par exemple, x86 32 bits) et des fonctions étrangères écrites dans des langages autres que C (par exemple C ++, Fortran).
  • Possibilité d'interagir avec les référentiels sur GitHub via des outils de ligne de commande
  • Performances: l'API Foreign Linker doit fournir des performances comparables ou supérieures à JNI.

12. Warnings for Value-Based Classes

Désignez les classes d'encapsuleur primitives comme étant basées sur la valeur et observez la suppression de leurs constructeurs, ce qui entraîne de nouveaux avertissements d'obsolescence. Fournit des avertissements concernant les tentatives de synchronisation incorrectes sur les instances de toute classe basée sur des valeurs dans la plate-forme Java.

Motivation Le projet Valhalla poursuit une amélioration significative du modèle de programmation Java sous la forme de classes primitives. Ces classes déclarent que leurs instances sont sans identité et capables de représentations en ligne ou aplaties, où les instances peuvent être copiées librement entre les emplacements de mémoire et encodées en utilisant uniquement les valeurs des champs des instances.

13. Packaging Tool

L'histoire L'outil jpackage a été introduit en tant qu'outil d'incubation dans le JDK 14 par JEP 343. Il est resté un outil d'incubation dans le JDK 15, afin de laisser du temps pour des commentaires supplémentaires. Il est maintenant prêt à passer de l'incubation à une fonction prête pour la production. En conséquence de cette transition, le nom du module jpackage passera de jdk.incubator.jpackage à jdk.jpackage. Le seul changement important par rapport à JEP 343 est que nous avons remplacé l'option --bind-services par l'option plus générale --jlink-options, décrite ci-dessous.

Buts Créez un outil de packaging, basé sur l'ancien outil JavaFX javapackager, qui: Prend en charge les formats d'emballage natifs pour offrir aux utilisateurs finaux une expérience d'installation naturelle. Ces formats incluent msi et exe sous Windows, pkg et dmg sous macOS, et deb et rpm sous Linux.

Permet de spécifier les paramètres de lancement au moment de l'emballage. Peut être appelé directement, à partir de la ligne de commande, ou par programme, via l'API ToolProvider.

14. Foreign-Memory Access API (Third Incubator)

s; Prise en charge des segments partagés; et La possibilité d'enregistrer des segments avec un nettoyeur.

  • Généralités: une seule API doit être capable de fonctionner sur différents types de mémoire étrangère (par exemple, mémoire native, mémoire persistante, mémoire de tas gérée, etc.).
  • Sécurité: il ne devrait pas être possible pour l'API de compromettre la sécurité de la JVM, quel que soit le type de mémoire utilisé.
  • Contrôle: les clients doivent avoir des options sur la manière dont les segments de mémoire doivent être désalloués: soit explicitement (via un appel de méthode), soit implicitement (lorsque le segment n'est plus utilisé).
  • Convivialité: pour les programmes qui ont besoin d'accéder à la mémoire étrangère, l'API doit être une alternative convaincante aux API Java héritées telles que sun.misc.Unsafe.

15. Correspondance de motifs (Pattern matching) par instanceof

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.

JEP

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

16.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à.

16.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.

16.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.

17. Strongly Encapsulate JDK Internals by Default

Encapsule fortement tous les éléments internes du JDK par défaut, à l'exception des API internes critiques telles que sun.misc.Unsafe. Permettez aux utilisateurs finaux de choisir l'encapsulation forte assouplie qui est la valeur par défaut depuis JDK 9.

Buts Continuer à améliorer la sécurité et la maintenabilité du JDK, qui est l'un des principaux objectifs de Project Jigsaw. Encouragez les développeurs à passer de l'utilisation d'éléments internes à l'utilisation d'API standard, afin qu'eux-mêmes et leurs utilisateurs puissent passer sans problème aux futures versions de Java.

18. Classes scellées (Sealed classes) (deuxième 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 {...}

fonctionnalité d’aperçu

19. Aller plus loin

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

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/ .

Vous pouvez lire des articles de développement intéressants ici : https://strong-programmer.com/fr/ .

20. Remerciements

Mickaël pour son aide inestimable sur la qualité globale de l'article : https://mbaron.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.