Alors que Java 16 est sorti il y a peu de temps (en mars 2021) je vous fais un petit bilan des gros points de cette version selon moi !

Les records sortent de preview

Petite nouveauté de Java 16 – qui traînent en preview depuis Java 14 – les records apportent une mécanique similaire aux data class de Kotlin.

Les records sont une nouvelle syntaxe beaucoup plus simple pour des classes pour représenter les données (plus de getter/setter/equals/hashCode/toString à coder/générer ! 🎉) et les instances de record sont immuables.

Niveau syntaxe je vous donne un aperçu :

record Person(
	String firstname,
	String lastname
) {
    // implicit members
    // private final String firstname
    // private final String lastname
    
    // implicit constructor
    // public Person(String firstname, String lastname) { ... }

	// implicit getter
    // public String firstname() { ... }
    // public String lastname() { ... }
    
    // implicit classical methods
    // public boolean equals(...) {...}
    // public int hashCode() {...}
    // public String toString() {...}

    // add custom method if needed
    public String fullname() {
        return p1.lastname()+" "+p1.firstName();
    }
}

var p1 = new Person("David", "Tennant");
System.out.println(p1.lastname().toUpperCase()+" "+p1.firstName());
System.out.println(p1.fullname());
System.out.println(p1.toString());

Si vous voulez en savoir plus sur les records je vous conseille de tester ! Personnellement j'ai déjà joué avec sur un projet perso en Quarkus ici : https://github.com/kuroidoruido/Collektor/blob/master/backend/src/main/java/nf/fr/k49/collektor/model/).

jpackage est prêt pour la production

Présent en preview depuis Java 14, jpackage est maintenant considéré comme suffisamment stable pour passer en production. jpackage prend globalement la suite du projet javapackager qui était prévu initialement pour les applications JavaFX et s'appuie sur jlink (présent dans le jdk depuis quelques versions) qui permet de créer des JVM customisée pour une application donnée.

L'idée derrière jpackage est de permettre la création de package prêt pour l'installation sur la machine d'un utilisateur avec un système d'installation standard pour Windows et de package standard pour Linux et macOS. Une manière simple de distribuer une application Java aux utilisateurs sans qu'il ait à s'occuper d'installer une version correcte de Java.

Vous pouvez trouver un exemple de son utilisation sur un autre de mes projets perso ici : https://github.com/kuroidoruido/SheepDoc/blob/master/.github/workflows/release.yml

À noter que jpackage est principalement prévu pour fonctionner sur des applications modulaires (JPMS) mais qu'il est possible de l'utiliser sur une application non modulaire avec un peu de configuration en plus (il faut commencer par exécuter jlink pour générer manuellement une JVM personnalisée, puis indiquer à jpackage de l'utiliser).

Passage sur Git et Github pour OpenJDK

Ce point est moins côté développeur Java, mais cette version marque l'abandon de Mercurial au profit de Git et de Github. Cette migration va permettre de plus facilement suivre et contribuer aux évolutions d'OpenJDK dans l'avenir ce qui ne peut être qu'une bonne chose !

Un pas de plus vers la fin des Primitive Wrapper

On est habitué en Java à distinguer double et Double, int et Integer, float et Float, boolean et Boolean, etc. Cette distinction est due à l'existance des types primitifs en Java qui ne sont pas des objets et donc ne peuvent pas être manipulé dans des collections ou des classes génériques. Le but de ce gros projet est de faire passer les types primitifs au statut d'objet et donc de ne plus avoir besoin de cette distinction.

Ici on en est pas encore là mais la JEPS 390 crée quelques changements autour des Primitive Wrapper. Le premier changement est l'ajout de la nouvelle annotation @jdk.internal.ValueBased de sorte à clairement les identifier pour le compilateur comme des value based object (comprendre : des objets qui ne font que contenir une valeur mais sont transparents pour des méthodes comme equals, au même titre que Optional ou Map.Entry ; la définition précise est ici : https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/doc-files/ValueBased.html). Ensuite le constructeur prenant en paramètre une valeur a été annoté en déprécié pour suppression (deprecated for removal), ce qui indique que ces constructeurs seront supprimés au passage à Java 17. Des outils ont été ajouté pour repérer les usages problématiques des Primitives Wrapper dans le code (via jdeprscan, javac et monitorenter de HotSpot) pour les retirer plus facilement.

Tout ceci s'inscrit dans le projet Valhalla, qui visent à moderniser très fortement le langage Java et son API et je pense que ça promet beaucoup de bonne chose dans le futur.

Une "petite" évolution de ZGC

Je n'avais pas prêté attention à ce changement à la première lecture de la note de version, mais en lisant un article traitant de ce changement après coup j'ai compris que j'avais loupé quelque chose d'important : ZGC est maintenant capable d'effectuer des pauses de garbage collecting en temps constant (par rapport à la taille de heap) inférieures à 1ms dans la plupart des cas.

Si vous ne savez pas comment fonctionne un garbage collector l'idée est simple : en tant que développeur, vous créez des objets, vous les déréférencez et vous ne vous occupez pas de la mémoire ; de temps en temps (en fonction de la stratégie du garbage collector qui a été choisi) le garbage collector met en pause tous les threads de JVM pour scanner l'intégralité de la mémoire, voir les instances d'objet qui ne sont plus référencés pour les éliminer (parfois avec un peu de réorganisation de la mémoire pour faire de l'optimisation). Vous vous doutez bien que si on effectue ce traitement de façon naïve (comme je viens de l'expliquer en gros) on peut se retrouver avec des pauses très longues pendant lesquels on ne peut effectuer aucune opération métier. Ici les développeurs ont réussi avec un peu d'astuce très peu coûteuse à rendre ce temps de pause presque inexistant, ce que je trouve extrêmement bluffant !

Conclusion

Je n'ai clairement pas cité tout le contenu de cette version mais ce qui m'a semblé le plus important aujourd'hui. Beaucoup de choses sont en mouvement dans le JDK pour améliorer fortement l'expérience de développement et ouvrir de nouvelle possibilité (je pense par exemple au pattern matching via instanceof). Plus que jamais Java est vivant et la version 17 (la prochaine LTS) sera un pas énorme pour tous ceux qui sont encore en Java 8 !

Petite astuce : vous pouvez tester une partie des nouveautés de Java 16 sans même créé de projet mais simplement en lançant un jshell avec l'option --enable-preview (pour être certain de pouvoir tout tester) 😎

jshell indique un warning pour le constructeur de Double

Sources :

Crédit photo : https://pixabay.com/photos/sixteen-number-street-address-4677399/