{"id":1684,"date":"2023-08-08T13:50:39","date_gmt":"2023-08-08T11:50:39","guid":{"rendered":"https:\/\/www.loicmathieu.fr\/wordpress\/?p=1684"},"modified":"2024-04-23T15:45:24","modified_gmt":"2024-04-23T13:45:24","slug":"java-21-quoi-de-neuf","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-21-quoi-de-neuf\/","title":{"rendered":"Java 21 : quoi de neuf ?"},"content":{"rendered":"<p>Maintenant que Java 21 est features complete (Rampdown Phase Two au jour d\u2019\u00e9criture de l\u2019article), c\u2019est le moment de faire le tour des fonctionnalit\u00e9s qu\u2019apporte cette nouvelle version, \u00e0 nous, les d\u00e9veloppeurs.<\/p>\n<p>Cet article fait partie d\u2019une suite d\u2019article sur les <a href=\"https:\/\/www.loicmathieu.fr\/wordpress\/tag\/whatsnew\/\">nouveaut\u00e9s des derni\u00e8res versions de Java<\/a>, pour ceux qui voudraient les lire en voici les liens : <a href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-20-quoi-de-neuf\/\">Java 20<\/a>, <a href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-19-quoi-de-neuf\/\">Java 19<\/a>, <a href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-18-quoi-de-neuf\/\">Java 18<\/a>, <a href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-17-quoi-de-neuf\/\">Java 17<\/a>, <a href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-16-quoi-de-neuf\/\">Java 16<\/a>, <a href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-15-quoi-de-neuf\/\">Java 15<\/a>, <a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-14-quoi-de-neuf\/\">Java 14<\/a>, <a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-13-quoi-de-neuf\/\">Java 13<\/a>, <a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-12-quoi-de-neuf\/\">Java 12<\/a>, <a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-11-quoi-de-neuf\/\">Java 11<\/a>,\u00a0<a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/informatique\/java-10-quoi-de-neuf\/\">Java 10,<\/a>\u00a0et\u00a0<a href=\"http:\/\/www.loicmathieu.fr\/wordpress\/informatique\/les-nouveautes-de-java-9-pour-les-developeurs\/\">Java 9<\/a>.<\/p>\n<p>Java 21 est la nouvelle version avec support \u00e0 long terme (Long Term Support &#8211; LTS), elle sera donc support\u00e9e pendant au moins 5 ans par Oracle. Au regard du nombre de JEP (Java Enhancement Proposals) qu&rsquo;elle contient, pas moins de 15, on voit tout de suite que c&rsquo;est une version riche en nouvelles fonctionnalit\u00e9s. Mais peut-\u00eatre le plus important (pour ne pas dire excitant) est le passage en final des virtual threads ! Les virtual threads sont des threads l\u00e9gers, avec un co\u00fbt de cr\u00e9ation et de scheduling faible, qui permettent de faciliter l\u2019\u00e9criture d\u2019application concurrente. Il faudra attendre quelque temps que l&rsquo;\u00e9cosyst\u00e8me les supporte, mais les virtual threads vont rendre Java pertinent pour des applications hautement concurrentes en environnement contraint en m\u00e9moire.<\/p>\n<h2>JEP 430 &#8211; String Templates (Preview)<\/h2>\n<p>Beaucoup de langages supportent l&rsquo;interpolation de cha\u00eenes de caract\u00e8res. L&rsquo;interpolation de cha\u00eenes de caract\u00e8res est un litt\u00e9ral de cha\u00eenes de caract\u00e8res contenant des expressions ainsi que du texte litt\u00e9ral.<\/p>\n<p>Par exemple, en Kotlin, <code>&quot;$x plus $y equals ${x + y}&quot;<\/code> est une cha\u00eene de caract\u00e8res contenant les expressions <code>$x<\/code>, <code>$y<\/code>, et <code>${x + y}<\/code> qui vont \u00eatre remplac\u00e9es par leur valeur textuelle. Ces valeurs sont dites interpol\u00e9es au sein de la cha\u00eene de caract\u00e8res. Cette interpolation se fait depuis les variables et permet des op\u00e9rations entre les variables (ici, une addition).<\/p>\n<p>Le probl\u00e8me de l&rsquo;interpolation est qu&rsquo;elle est dangereuse en tant que fonctionnalit\u00e9 globale, car elle ne permet pas de validation ou d&rsquo;assainissement (sanitization) lors de la construction de la cha\u00eene de caract\u00e8re finale. Elle s&rsquo;expose donc, par exemple, aux injections SQL ou JavaScript.<\/p>\n<p>Les String Templates en Java proposent de l&rsquo;interpolation de cha\u00eenes de caract\u00e8res int\u00e9grant la validation et l&rsquo;assainissement via un processeur de template.<\/p>\n<p>Un processeur de template prend un template, puis va r\u00e9aliser l&rsquo;interpolation du template vers un objet d&rsquo;un type pr\u00e9cis ; on peut donc depuis un template interpoler une <code>String<\/code>, ou un <code>PreparedStatement<\/code>, ou un <code>JSONObject<\/code>, &#8230; Comme il est possible d&rsquo;avoir plusieurs processeurs, chacun peut impl\u00e9menter une \u00e9tape de validation si n\u00e9cessaire.<\/p>\n<p>Voici un exemple d&rsquo;utilisation du String Template <code>STR<\/code>, il ne comporte pas de validation sp\u00e9cifique et peut \u00eatre utilis\u00e9 pour remplacer de la concat\u00e9nation de cha\u00eene de caract\u00e8re :<\/p>\n<pre>String firstName = \"Lo\u00efc\";\nString lastName  = \"Mathieu\";\nString helloWorld  = STR.\"Hello \\{firstName} \\{lastName}\";\n<\/pre>\n<p>En Java, les expressions sont d\u00e9finies par <code>{expression}<\/code>, et l&rsquo;appel d&rsquo;un processeur de template se fait via son nom, ici FMT qui est une constante de l&rsquo;interface <code>StringTemplate<\/code> qui aura \u00e9t\u00e9 pr\u00e9c\u00e9demment import\u00e9e via un import statique.<\/p>\n<p>Il y a eu beaucoup de discussion autour du choix du format des expressions. \u00c0 cause de l\u2019existence de nombreuses librairies utilisant $, # ou {} comme d\u00e9limiteur d&rsquo;expression, le choix a \u00e9t\u00e9 d&rsquo;un format qui n&rsquo;est pas valide en dehors des String Templates : <code>String s = &quot;Hello {firstName} {lastName}&quot;<\/code> ne compile pas. Cela permet de distinguer les String Templates des Strings simple.<\/p>\n<p>La librairie standard inclue trois processeurs de template :<\/p>\n<ul><li><code>RAW<\/code> : processeur qui n\u2019interpole pas les cha\u00eenes de caract\u00e8re, permet des manipulations bas niveau.<\/li>\n\n<li><code>STR<\/code> : processeur qui interpole une cha\u00eene de caract\u00e8re vers une autre cha\u00eene de caract\u00e8re via concat\u00e9nation simple.<\/li>\n\n<li><code>FMT<\/code> : processeur qui interpole une cha\u00eene de caract\u00e8re vers une autre cha\u00eene de caract\u00e8re en permettant de formater les expressions via un <a title=\"Formatter API doc\" href=\"https:\/\/download.java.net\/java\/early_access\/jdk21\/docs\/api\/java.base\/java\/util\/Formatter.html\" target=\"_blank\" rel=\"noopener\">Formatter<\/a>, par exemple <code>FMT.&quot;%05d\\{x} + %05d\\{y} = %05d\\{x + y}&quot;;<\/code><\/li>\n<\/ul>\n<p>Il est possible de cr\u00e9er ses propres processeurs en impl\u00e9mentant l&rsquo;interface <code>StringTemplate.Processor<\/code>.<\/p>\n<p>Plus d\u2019information dans la <a title=\"JEP 430\" href=\"https:\/\/openjdk.org\/jeps\/430\" target=\"_blank\" rel=\"noopener\">JEP 430<\/a>.<\/p>\n<h2>JEP 431 &#8211; Sequenced Collections<\/h2>\n<p>L&rsquo;API de collection de Java a vu un ajout dans Java 21 d&rsquo;une importance qui n&rsquo;avait pas \u00e9t\u00e9 vu depuis de tr\u00e8s nombreuses releases !<\/p>\n<p>Les collections en Java n&rsquo;ont pas de type repr\u00e9sentant une s\u00e9quence ordonn\u00e9e d&rsquo;\u00e9l\u00e9ments, Java 21 viens combler ce manque en introduisant les interfaces <code>SequencedCollection<\/code>, <code>SequencedSet<\/code> et <code>SequencedMap<\/code>. Ces interfaces proposent des m\u00e9thodes permettant d&rsquo;ajouter, de modifier ou de supprimer des \u00e9l\u00e9ments au d\u00e9but ou a la fin de la collection, ainsi que d&rsquo;it\u00e9rer sur une collection en sens inverse.<\/p>\n<p>Voici l&rsquo;interface <code>SequencedCollection<\/code> :<\/p>\n<pre>interface SequencedCollection extends Collection {\n    SequencedCollection reversed();\n    void addFirst(E);\n    void addLast(E);\n    E getFirst();\n    E getLast();\n    E removeFirst();\n    E removeLast();\n}\n<\/pre>\n<p>La m\u00e9thode <code>reversed()<\/code> va retourner une vue de la collection dans un ordre invers\u00e9, une modification de la collection d&rsquo;origine impactera la vue invers\u00e9e.<\/p>\n<p><code>SequencedSet<\/code> est un set qui est aussi une <code>SequencedCollection<\/code>, voici son interface :<\/p>\n<pre>interface SequencedSet extends Set, SequencedCollection {\n    SequencedSet reversed();\n}\n<\/pre>\n<p><code>SequencedMap<\/code> est une map dont les entr\u00e9es sont ordonn\u00e9es, voici son interface :<\/p>\n<pre>interface SequencedMap extends Map {\n    SequencedMap reversed();\n    SequencedSet sequencedKeySet();\n    SequencedCollection sequencedValues();\n    SequencedSet&lt;Entry&gt; sequencedEntrySet();\n    V putFirst(K, V);\n    V putLast(K, V);\n    Entry firstEntry();\n    Entry lastEntry();\n    Entry pollFirstEntry();\n    Entry pollLastEntry();\n}\n<\/pre>\n<p>Ces nouvelles interfaces ont \u00e9t\u00e9 int\u00e9gr\u00e9es dans la hi\u00e9rarchie existante des classes de l&rsquo;API Collection.<\/p>\n<img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large\" src=\"https:\/\/i0.wp.com\/cr.openjdk.org\/~smarks\/collections\/SequencedCollectionDiagram20220216.png?resize=640%2C356&#038;ssl=1\" alt=\"Java Collection API hierarchy\" width=\"640\" height=\"356\" \/>\n<p>On peut noter que certaines des impl\u00e9mentations les plus utilis\u00e9es de l&rsquo;API Collection : <code>ArrayList<\/code>, <code>LinkedList<\/code>, <code>LinkedHashMap<\/code> et <code>LinkedHashSet<\/code> sont maintenant des collections s\u00e9quentielles.<\/p>\n<p>Plus d\u2019information dans la <a title=\"JEP 431\" href=\"https:\/\/openjdk.org\/jeps\/431\" target=\"_blank\" rel=\"noopener\">JEP 431<\/a>.<\/p>\n<h2>JEP 443 &#8211; Unnamed Patterns and Variables Preview)<\/h2>\n<p>Cette nouvelle fonctionnalit\u00e9 du langage Java permet d&rsquo;utiliser <code>&lt;em&gt;<\/code> comme pattern ou variable anonyme (litt\u00e9ralement sans nom ou non-nomm\u00e9). Le but est d&rsquo;utiliser <code>&lt;\/em&gt;<\/code> pour d\u00e9noter un pattern ou une variable inutile, le compilateur s&rsquo;assurera alors que la variable est r\u00e9ellement non utilis\u00e9e car elle n&rsquo;a pas de nom.<\/p>\n<p>Au sein du pattern matching de Java, <code>&lt;em&gt;<\/code> peut \u00eatre utilis\u00e9 comme pattern anonyme, par exemple dans un instanceof : <code>instanceof Point(&lt;\/em&gt;, int y)<\/code>; ou comme variable de pattern anonyme, par exemple dans un instanceof : <code>instanceof Point(int &lt;em&gt;, int y)<\/code> ou dans un switch : <code>case Box(GreenBall &lt;\/em&gt;)<\/code>.<\/p>\n<p><code>_<\/code> peut aussi \u00eatre utilis\u00e9 pour d\u00e9noter une variable anonyme qui ne pourra ni \u00eatre lue ni \u00eatre \u00e9crite ; comme elle n&rsquo;a pas de nom, on peut utiliser plusieurs variables anonymes dans un m\u00eame scope.<\/p>\n<p>On peut utiliser une variable anonyme :<\/p>\n<ul><li>Comme une variable locale a un statement,<\/li>\n\n<li>Comme une ressource d&rsquo;un try-with-resource,<\/li>\n\n<li>Dans un ent\u00eate d&rsquo;une boucle for (basique ou enhanced),<\/li>\n\n<li>Comme une exception en param\u00e8tre d&rsquo;un bloc catch,<\/li>\n\n<li>Comme un param\u00e8tre d&rsquo;une expression lambda.<\/li>\n<\/ul>\n<p>Voici quelques exemples tir\u00e9s de la JEP 443 :<\/p>\n<pre>\/\/ enhanced for loop\nint acc = 0;\nfor (Order _ : orders) {\n    if (acc &lt; LIMIT) { ... acc++ ... } \n} \n\n\/\/ block statement \nQueue \nq = ... \/\/ x1, y1, z1, x2, y2, z2, ... \nwhile (q.size() &gt;= 3) {\n   var x = q.remove();\n   var y = q.remove();\n   var _ = q.remove();\n   ... new Point(x, y) ...\n}\n\n\/\/ catch block\nString s = ...\ntry { \n    int i = Integer.parseInt(s);\n    ... i ...\n} catch (NumberFormatException _) { \n    System.out.println(\"Bad number: \" + s);\n}\n\n\/\/ try-with-resources\ntry (var _ = ScopedContext.acquire()) {\n    ... no use of acquired resource ...\n}\n\n\/\/ lamdba parameter\nstream.collect(Collectors.toMap(String::toUpperCase, _ -&gt; \"NODATA\"))\n<\/pre>\n<p>Cette fonctionnalit\u00e9, m\u00eame si elle peut sembler petite, est en fait une fonctionnalit\u00e9 tr\u00e8s attendue et qui peut fortement am\u00e9liorer la lisibilit\u00e9 du code et \u00e9viter de possibles bugs en d\u00e9notant clairement qu&rsquo;une variable ne doit pas \u00eatre utilis\u00e9e. On peut juste regretter que, pour l&rsquo;instant, il ne soit pas possible d&rsquo;utiliser <code>_<\/code> comme un param\u00e8tre de m\u00e9thode surcharg\u00e9e.<\/p>\n<p>Plus d\u2019information dans la <a title=\"JEP 443\" href=\"https:\/\/openjdk.org\/jeps\/443\" target=\"_blank\" rel=\"noopener\">JEP 443<\/a>.<\/p>\n<h2>JEP 445: Unnamed Classes and Instance Main Methods (Preview)<\/h2>\n<p>Le but de cette nouvelle fonctionnalit\u00e9 est de faciliter l&rsquo;apprentissage de Java et simplifier son utilisation pour des cas simple, entre autres, pour l&rsquo;\u00e9criture d&rsquo;une simple m\u00e9thode main.<\/p>\n<p>Prenons comme exemple un \u00ab\u00a0Hello World\u00a0\u00bb en Java :<\/p>\n<pre>public class HelloWorld { \n    public static void main(String[] args) { \n        System.out.println(\"Hello, World!\");\n    }\n}\n<\/pre>\n<p>Pour simplement \u00e9crire \u00ab\u00a0Hello World\u00a0\u00bb dans la consoles il faut connaitre les principes de classe, de m\u00e9thode, de visibilit\u00e9, du modificateur static, ainsi que la signature tr\u00e8s particuli\u00e8re de la m\u00e9thode main en Java : la m\u00e9thode qui sera ex\u00e9cut\u00e9e comme point d&rsquo;entr\u00e9e du programme.<\/p>\n<p>Premier changement : permettre une m\u00e9thode main non statique (m\u00e9thode d&rsquo;instance), non publique, et sans param\u00e8tre :<\/p>\n<pre>class HelloWorld { \n    void main() { \n        System.out.println(\"Hello, World!\");\n    }\n}\n<\/pre>\n<p>Second changement : l&rsquo;introduction des classes anonymes (non-nomm\u00e9es) :<\/p>\n<pre>void main() {\n    System.out.println(\"Hello, World!\");\n}\n<\/pre>\n<p>Une classe anonyme est une classe dans un fichier .class qui n&rsquo;a pas de d\u00e9claration de classe, elle ne peut pas \u00eatre appel\u00e9e par une autre classe, mais peut contenir des m\u00e9thodes et des champs. Elle se trouve dans un package anonyme.<\/p>\n<p>Ces deux nouveaut\u00e9s, bien que ciblant les d\u00e9veloppeurs apprenant Java, peuvent grandement faciliter l&rsquo;\u00e9criture de petit programme en Java en r\u00e9duisant la c\u00e9r\u00e9monie autour de l&rsquo;\u00e9criture du point d&rsquo;entr\u00e9e d&rsquo;un programme Java.<\/p>\n<p>Lors de discussion autour de cette fonctionnalit\u00e9, il a aussi \u00e9t\u00e9 abord\u00e9 le cas de <code>System.out.println()<\/code> (ainsi que la lecture depuis la console) et de possible simplification. Il se peut que dans une prochaine version de Java des simplifications \u00e0 ce sujet soit int\u00e9gr\u00e9es.<\/p>\n<p>Plus d\u2019information dans la <a title=\"JEP 445\" href=\"https:\/\/openjdk.org\/jeps\/445\" target=\"_blank\" rel=\"noopener\">JEP 445<\/a>.<\/p>\n<h2>Les fonctionnalit\u00e9s qui sortent de preview<\/h2>\n<p>Les fonctionnalit\u00e9s suivantes sortent de preview (ou du module incubator) et passent en standard :<\/p>\n<ul><li><a title=\"JEP 440\" href=\"https:\/\/openjdk.org\/jeps\/440\" target=\"_blank\" rel=\"noopener\">JEP 440<\/a> &#8211; Record Patterns : enrichit le pattern matching de Java avec les record patterns qui permettent de d\u00e9construire un record en ses attributs.<\/li>\n\n<li><a title=\"JEP 441\" href=\"https:\/\/openjdk.org\/jeps\/441\" target=\"_blank\" rel=\"noopener\">JEP 441<\/a> &#8211; Pattern Matching for switch : permet de faire un switch sur le type d\u2019une variable (y compris enum, record et tableau), et en extraire une variable locale au case qui sera du type correspondant.<\/li>\n\n<li><a title=\"JEP 444\" href=\"https:\/\/openjdk.org\/jeps\/444\" target=\"_blank\" rel=\"noopener\">JEP 444<\/a> &#8211; Virtual Threads : parfois aussi nomm\u00e9s green threads ou lightweight threads; ce sont des threads l\u00e9gers, avec un co\u00fbt de cr\u00e9ation et de scheduling faible, qui permettent de faciliter l\u2019\u00e9criture d\u2019application concurrente.<\/li>\n<\/ul>\n<p>Pour les d\u00e9tails sur celles-ci, vous pouvez vous r\u00e9f\u00e9rer \u00e0 mes articles pr\u00e9c\u00e9dents.<\/p>\n<h2>Les fonctionnalit\u00e9s qui restent en preview<\/h2>\n<p>Les fonctionnalit\u00e9s suivantes restent en preview (ou en incubator module).<\/p>\n<ul><li><a title=\"JEP 442\" href=\"https:\/\/openjdk.org\/jeps\/442\" target=\"_blank\" rel=\"noopener\">JEP 442<\/a> &#8211; Foreign Function &amp; Memory API (Third Preview) : am\u00e9lioration suite aux retours de la preview. La gestion des segments m\u00e9moire natifs est d\u00e9sormais faite via une nouvelle API <code>Arena<\/code>.<\/li>\n\n<li><a title=\"JEP-448\" href=\"https:\/\/openjdk.org\/jeps\/448\" target=\"_blank\" rel=\"noopener\">JEP-448<\/a> \u2013 Vector API : sixi\u00e8me incubation de la fonctionnalit\u00e9. Cette nouvelle version inclut des bugfixes et des am\u00e9liorations de performance.<\/li>\n\n<li><a title=\"JEP 446\" href=\"https:\/\/openjdk.org\/jeps\/446\" target=\"_blank\" rel=\"noopener\">JEP 446<\/a> &#8211; Scoped Values (Preview) : pr\u00e9c\u00e9demment en incubation, permettent le partage de donn\u00e9es immuables au sein et entre les threads.<\/li>\n\n<li><a title=\"JEP 453\" href=\"https:\/\/openjdk.org\/jeps\/453\" target=\"_blank\" rel=\"noopener\">JEP 453<\/a> &#8211; Structured Concurrency (Preview) : pr\u00e9c\u00e9demment en incubation, nouvelle API permettant de simplifier l\u2019\u00e9criture de code multi-thread\u00e9 en permettant de traiter plusieurs t\u00e2ches concurrentes comme une unit\u00e9 de traitement unique.<\/li>\n<\/ul>\n<p>Pour les d\u00e9tails sur celles-ci, vous pouvez vous r\u00e9f\u00e9rer \u00e0 mes articles pr\u00e9c\u00e9dents.<\/p>\n<h2>Divers<\/h2>\n<p>Divers ajouts au JDK :<\/p>\n<ul><li><code>Character.isEmoji()<\/code>, <code>Character.isEmojiPresentation()<\/code>, <code>Character.isEmojiModifier()<\/code>, <code>Character.isEmojiModifierBase()<\/code>, <code>Character.isEmojiComponent()<\/code>, <code>Character.isExtendedPictographic()<\/code>.<\/li>\n\n<li><code>Math.clamp()<\/code> et <code>StrictMath.clamp()<\/code> : restreint une valeur entre deux bornes min et max.<\/li>\n\n<li><code>StringBuilder.repeat()<\/code> : joint un caract\u00e8re ou une cha\u00eene de caract\u00e8re un certain nombre de fois.<\/li>\n\n<li><code>HttpClient<\/code> impl\u00e9mente maintenant <code>AucoCloseable<\/code> et peut donc \u00eatre utilis\u00e9 plus facilement dans un bloc try-with-resources.<\/li>\n\n<li><code>Locale.availableLocales()<\/code> : retourne la liste des locales install\u00e9es.<\/li>\n\n<li><code>Collections.shuffle(List, RandomGenerator)<\/code> : effectue des permutations al\u00e9atoires des \u00e9l\u00e9ments de la liste depuis un <code>RandomGenerator<\/code>.<\/li>\n\n<li><code>String.splitWithDelimiters()<\/code> et <code>Pattern.splitWithDelimiters()<\/code> : scinde une cha\u00eene de caract\u00e8res en incluant les d\u00e9limiteurs.<\/li>\n<\/ul>\n<p>La totalit\u00e9 des nouvelles API du JDK 21 peuvent \u00eatre trouv\u00e9es dans <a title=\"The Java Version Almanac \u2013 New APIs in Java 21\" href=\"https:\/\/javaalmanac.io\/jdk\/21\/apidiff\/20\/\" target=\"_blank\" rel=\"noopener\">The Java Version Almanac \u2013 New APIs in Java 21<\/a>.<\/p>\n<h2>Des changements internes, de la performance, et de la s\u00e9curit\u00e9<\/h2>\n<p>Le Garbage Collector ZGC devient g\u00e9n\u00e9rationnel, il peut donc s\u00e9parer la heap en plusieurs zones en fonction de l&rsquo;\u00e2ge des objets. Pour utiliser cette fonctionnalit\u00e9 il faut utiliser l&rsquo;option ligne de commande <code>-XX:+ZGenerational<\/code>. Ce Garbage Collector a \u00e9t\u00e9 cr\u00e9\u00e9 pour supporter des heaps de tailles tr\u00e8s importantes (plusieurs terraoctets) avec des pauses tr\u00e8s faibles (de l&rsquo;ordre de la milliseconde). L&rsquo;ajout d&rsquo;une heap g\u00e9n\u00e9rationnelle lui permet de supporter des workloads diff\u00e9rents en consommant moins de ressources. Plus d\u2019information dans la <a title=\"JEP 439\" href=\"https:\/\/openjdk.org\/jeps\/439\" target=\"_blank\" rel=\"noopener\">JEP 439<\/a>.<\/p>\n<p>G1 GC a, lui aussi, profit\u00e9 de quelques nouvelles optimisations : les full GCs ont \u00e9t\u00e9 optimis\u00e9s et le Hot Card Cache qui s&rsquo;av\u00e9rait n&rsquo;apporter aucun avantage a \u00e9t\u00e9 supprim\u00e9, lib\u00e9rant de la m\u00e9moire native (0,2% de la taille de la heap). D\u2019autres changements ont \u00e9t\u00e9 faits c\u00f4t\u00e9 Garbage Collector, vous pouvez les retrouver dans cet article de Thomas Schatzl : <a href=\"https:\/\/tschatzl.github.io\/2023\/08\/04\/jdk21-g1-parallel-gc-changes.html\" target=\"_blank\" rel=\"noopener\">JDK 21 G1\/Parallel\/Serial GC changes<\/a>.<\/p>\n<p>C\u00f4t\u00e9 s\u00e9curit\u00e9, Java supporte maintenant les m\u00e9canismes d&rsquo;encapsulation de cl\u00e9 (Key Encapsulation Mechanism &#8211; KEM), une technique de chiffrement pour s\u00e9curiser les cl\u00e9s sym\u00e9triques \u00e0 l&rsquo;aide de la cryptographie \u00e0 cl\u00e9 publique. Plus d\u2019information \u00e0 ce sujet dans la <a title=\"JEP 452\" href=\"https:\/\/openjdk.org\/jeps\/452\" target=\"_blank\" rel=\"noopener\">JEP 452<\/a>.\nLe support de v\u00e9rification de signature de type Leighton-Micali Signature (LMS) ainsi que les algorithme de cryptographie de type PBES2 ont \u00e9t\u00e9 ajout\u00e9, vous pouvez vous r\u00e9f\u00e9rer \u00e0 l\u2019article de Sean Mullan pour une liste exhaustive des changements de s\u00e9curit\u00e9 inclus cette version : <a href=\"https:\/\/seanjmullan.org\/blog\/2023\/09\/22\/jdk21\" rel=\"noopener\" target=\"_blank\">JDK 21 Security Enhancements<\/a>.<\/p>\n<p>Le port pour Windows 32-bit pour CPU x86 a \u00e9t\u00e9 d\u00e9pr\u00e9ci\u00e9 pour suppression dans une prochaine release. Windows 10, la derni\u00e8re version de Windows supportant les architectures 32-bit, sera en fin de vie en octobre 2025. D\u00e9pr\u00e9cier puis supprimer le port Windows 32-bit permettra de simplifier le build l&rsquo;Open JDK et de r\u00e9duire son co\u00fbt de maintenance. Plus d\u2019information dans la <a title=\"JEP 449\" href=\"https:\/\/openjdk.org\/jeps\/449\" target=\"_blank\" rel=\"noopener\">JEP 449<\/a>.<\/p>\n<p>Le chargement dynamique d&rsquo;agent Java est maintenant d\u00e9pr\u00e9ci\u00e9 pour suppression. Si utilis\u00e9, il affichera un WARNING dans les logs de la JVM. Le chargement d&rsquo;un agent Java au d\u00e9marrage de l&rsquo;application reste support\u00e9, c&rsquo;est uniquement le chargement dynamique apr\u00e8s le d\u00e9marrage d&rsquo;une application qui est d\u00e9pr\u00e9ci\u00e9. Le but est d&rsquo;am\u00e9liorer l&rsquo;int\u00e9grit\u00e9 de la JVM, un agent pouvant modifier le code d&rsquo;une application, le charger apr\u00e8s d\u00e9marrage de la JVM est un risque de s\u00e9curit\u00e9. Plus d\u2019information dans la <a title=\"JEP 451\" href=\"https:\/\/openjdk.org\/jeps\/451\" target=\"_blank\" rel=\"noopener\">JEP 451<\/a>.<\/p>\n<p>C\u00f4t\u00e9 performance, Per Minborg a r\u00e9alis\u00e9 des am\u00e9liorations dans la conversion entre les primitifs (long vers int par exemple) via l&rsquo;utilisation de <code>VarHandle<\/code> en remplacement des calculs binaires existants. Ces op\u00e9rations de conversions \u00e9tant tr\u00e8s utilis\u00e9 au sein de la s\u00e9rialisation Java, celle-ci en tire parti et voit une am\u00e9lioration de performance de pr\u00e8s de 5%. D&rsquo;autres API du JDK ainsi que de nombreuses librairies utilisent aussi ces conversions et verront leur performance s&rsquo;am\u00e9liorer. Plus d&rsquo;information dans l&rsquo;article de Per Minborg : <a href=\"https:\/\/minborgsjavapot.blogspot.com\/2023\/01\/java-21-performance-improvements.html\" target=\"_blank\" rel=\"noopener\">Java 21: Performance Improvements Revealed<\/a>.<\/p>\n<h2>Conclusion<\/h2>\n<p>Au vu du nombre tr\u00e8s important de fonctionnalit\u00e9s inclues dans Java 21, on peut s&rsquo;attendre \u00e0 ce que Java 22 soit une release de stabilisation. J&rsquo;esp\u00e8re que certaines fonctionnalit\u00e9s sortiront de preview en Java 22 (ce qui devrait \u00eatre le cas pour la Foreign Function &amp; Memory API), tout particuli\u00e8rement les Scoped Values et la Structured Concurrency qui compl\u00e9mentent les Virtual Threads en facilitant l&rsquo;\u00e9criture d&rsquo;application concurrente.<\/p>\n<p>Pour retrouver tous les changements de Java 21, se r\u00e9f\u00e9rer aux <a title=\"release notes\" href=\"https:\/\/jdk.java.net\/21\/release-notes\" target=\"_blank\" rel=\"noopener\">release notes<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Maintenant que Java 21 est features complete (Rampdown Phase Two au jour d\u2019\u00e9criture de l\u2019article), c\u2019est le moment de faire le tour des fonctionnalit\u00e9s qu\u2019apporte cette nouvelle version, \u00e0 nous, les d\u00e9veloppeurs. Cet article fait partie d\u2019une suite d\u2019article sur les nouveaut\u00e9s des derni\u00e8res versions de Java, pour ceux qui voudraient les lire en voici les liens : Java 20, Java 19, Java 18, Java 17, Java 16, Java 15, Java 14, Java 13, Java 12, Java 11,\u00a0Java 10,\u00a0et\u00a0Java 9&#8230;.<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-21-quoi-de-neuf\/\">Lire la suite<span class=\"screen-reader-text\"> Lire la suite<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[11,218,163],"class_list":["post-1684","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-java","tag-java21","tag-whatsnew"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":856,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-next\/","url_meta":{"origin":1684,"position":0},"title":"Java.Next","author":"admin","date":"mercredi 31 octobre 2018","format":false,"excerpt":"Ma premi\u00e8re contribution au blog de Zenika est un article qui parle du futur (ou du pr\u00e9sent) de Java et des changements pour les d\u00e9veloppeurs dans les versions 9, 10 et 11. La gouvernance de Java y est aussi abord\u00e9. Cet article reprend et r\u00e9sume les articles que j'ai pr\u00e9c\u00e9demment\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":829,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-11-quoi-de-neuf\/","url_meta":{"origin":1684,"position":1},"title":"Java 11  : quoi de neuf ?","author":"admin","date":"lundi  1 octobre 2018","format":false,"excerpt":"Maintenant que Java 11 est sorti, c'est le moment de faire le tour des fonctionnalit\u00e9s qu'apporte cette version, \u00e0 nous, les d\u00e9veloppeurs. Cet article fait partie d\u2019une suite d\u2019article sur les nouveaut\u00e9s des derni\u00e8res version de Java, pour ceux qui voudraient les lires en voici les liens : Java 10,\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":712,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/demarrage-jvm-8-vs-9\/","url_meta":{"origin":1684,"position":2},"title":"D\u00e9marrage JVM 8 vs 9","author":"admin","date":"jeudi 31 ao\u00fbt 2017","format":false,"excerpt":"Introduction En parcourant la mailing liste d'open JDK (core-lib-dev) j'ai vu plusieurs threads de mail \u00e0 propos d'optimisation de temps de d\u00e9marrage et d'occupation m\u00e9moire d'une JVM \"minimale\". Ce travail a \u00e9t\u00e9 r\u00e9alis\u00e9 en grande partie par Claes Redestad (Oracle) lors du d\u00e9veloppement de Java 9. J'ai donc d\u00e9cid\u00e9 de\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":722,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-10-quoi-de-neuf\/","url_meta":{"origin":1684,"position":3},"title":"Java 10 : quoi de neuf ?","author":"admin","date":"lundi 26 mars 2018","format":false,"excerpt":"Maintenant que Java 10 est sorti, il est temps de se pencher sur les nouveaut\u00e9s de cette version. Comme pour mon pr\u00e9c\u00e9dent article sur java 9, je vais me pencher principalement sur les changements qui impacterons les d\u00e9veloppeurs utilisant Java en laissant de c\u00f4t\u00e9 les changements internes\/anecdotique\/sur des API peu\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1839,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-vers-une-integrite-par-defaut-de-la-jvm\/","url_meta":{"origin":1684,"position":4},"title":"Java : vers une int\u00e9grit\u00e9 par d\u00e9faut de la JVM","author":"admin","date":"mardi  4 f\u00e9vrier 2025","format":false,"excerpt":"Cet article est paru pour la premi\u00e8re fois dans le magazine Programmez! Hors s\u00e9rie #16. La Machine Virtuelle Java (JVM) est un environnement d'ex\u00e9cution qui permet \u00e0 des programmes \u00e9crits en Java (ou dans d'autres langages compil\u00e9s en bytecode Java) de s'ex\u00e9cuter sur diff\u00e9rents syst\u00e8mes d'exploitation et architectures mat\u00e9rielles. D\u00e8s\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1112,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-15-quoi-de-neuf\/","url_meta":{"origin":1684,"position":5},"title":"Java 15 : quoi de neuf ?","author":"admin","date":"jeudi  2 juillet 2020","format":false,"excerpt":"Maintenant que Java 15 est features complete (Rampdown Phase One au jour d\u2019\u00e9criture de l\u2019article), c\u2019est le moment de faire le tour des fonctionnalit\u00e9s qu\u2019apporte cette nouvelle version, \u00e0 nous, les d\u00e9veloppeurs. Cet article fait partie d\u2019une suite d\u2019article sur les nouveaut\u00e9s des derni\u00e8res versions de Java, pour ceux qui\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1684","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/comments?post=1684"}],"version-history":[{"count":32,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1684\/revisions"}],"predecessor-version":[{"id":1812,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1684\/revisions\/1812"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/media?parent=1684"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/categories?post=1684"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/tags?post=1684"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}