Notre

blog

Java 25 : ce qu’il faut retenir de la dernière version LTS

Java 25 : ce qu’il faut retenir de la dernière version LTS

Le 16 septembre dernier, Oracle a officiellement publié Java 25, une version Long-Term Support (LTS) qui introduit un ensemble ambitieux de nouveautés, tant au niveau du langage, des API que de la JVM.

C’est la première version LTS après Java 21, ce qui en fait une cible de migration stratégique pour de nombreux projets d’entreprise.

Quelles sont les fonctionnalités les plus marquantes de cette nouvelle version ? Quels sont les bénéfices attendus ?

Quoi de neuf dans Java 25 ?

Java 25 embarque 18 JEPs (Java Enhancement Proposals), répartis entre fonctionnalités finalisés et previews.

Fonctionnalités finalisées majeures

  1. Scoped Values (JEP 506) : Cette API permet de partager des données immuables entre un thread et ses fils sans recourir à ThreadLocal. L’idée est de proposer un mécanisme plus léger et plus fluide, particulièrement utile en combinaison avec les virtuals threads.
  2. Module Import Declarations (JEP 511) : Cette fonctionnalité permet de spécifier dans le fichier source que certains modules sont importés (via import module …), ce qui rend les dépendances de module plus explicitement visibles dans le code.
    Cela simplifie la gestion des modules, notamment dans des projets modulaires complexes.
  3. Compact Source Files & Instance Main Methods (JEP 512) : Pour les programmes simples ou les démonstrations, Java 25 permet d’écrire des fichiers source sans classe explicites et d’avoir une méthode main() non statique plus simple.

    Exemple :
    void main() {
    IO.println(« Hello world! »);
    }

    Avec ce JEP, l’import implicite de java.base et la classe utilitaire IO facilitent l’écriture rapide de petits programmes.
  4. Flexible Constructor Bodies (JEP 513) : Avec cette nouveauté, il est désormais possible d’exécuter des validations ou calculs préliminaires avant l’appel au constructeur parent, tant que l’on ne lit pas de champs non initialisés.

    Ceci rend le code plus lisible et évite des contorsions syntaxiques autour de l’ordre d’appel des constructeurs.

Optimisations, observabilité & performances

Compact Object Headers (JEP 519) : Réduction de la surcharge mémoire des en-têtes d’objet dans le JVM HotSpot, passant de 12 octets à 8 octets dans certaines configurations. Cela améliore la densité mémoire et les performances, surtout si l’application manipule de nombreux petits objets.

Generational Shenandoah (JEP 521) : Le célèbre ramasse-miettes Shenandoah passe à un mode « générationnel », ce qui peut améliorer la réactivité, la résilience aux pics de charge et l’efficacité mémoire dans les applications intensives.

Améliorations du JDK Flight Recorder (JFR) :

  • CPU-time profiling (experimental, JEP 509) : capture du temps CPU à un niveau fin (par méthode) sur Linux, pour aider à identifier les vrais goulots d’exécution.
  • Cooperative Sampling (JEP 518) : échantillonnage plus coopératif entre les threads pour mieux répartir la charge et améliorer la précision.
  • Method Timing & Tracing (JEP 520) : mesure fine du temps passé par méthode, ce qui affine la compréhension du comportement runtime.

Ahead-of-Time Method Profiling (JEP 515) : Ce JEP permet de générer au démarrage des profils d’usage des méthodes (à partir de traces précédemment collectées) afin d’orienter le compilateur JIT pour une meilleure optimisation initiale. Cela améliore le temps de démarrage, un point critique pour les microservices ou les environnements “serverless”.

Autres optimisations / ajustements

  • Nouveaux algorithmes de “Ahead-of-Time command-line ergonomics” (JEP 514) pour faciliter l’usage des options CLI.
  • Dépréciation ou retrait du port 32 bits x86 (JEP 503) : Java 25 abandonne le support du port 32 bits sur x86.
  • API “Key Derivation Function” (JEP 510), utile dans les scénarios cryptographiques modernes, notamment face aux avancées vers la cryptographie post-quantique.

Previews, features à venir

Stable Values (JEP 502) : Introduction d’une API permettant d’initialiser des valeurs grâce à des fonctions lambda qui seront traités comme immutables par la suite. Globalement, cela va permettre d’avoir les optimisations de performance de l’utilisation du mot clé final, tout en gagnant en flexibilité sur la déclaration de la valeur.

Primitive Types in Patterns, instance of and switch (JEP 507) : Tout simplement pouvoir utiliser les types primitifs dans plus de contextes.

Quels gains pour les projets et les équipes ?

Productivité & lisibilité

• Le support de Flexible Constructor Bodies et la réduction du “boilerplate” rendent le code plus lisible, plus expressif, moins verbeux.

• Les previews sur les motifs (patterns) avec types primitifs étendent le pouvoir expressif des switch/instanceof.

Performance & observabilité

• Les améliorations de JFR facilitent le diagnostic fin des performances, ce qui est crucial dans les architectures distribuées ou critiques.
• La génération de profils AOT peut améliorer le temps de “warm-up” dans les environnements à forte exigence de latence.
• Le mode générational pour Shenandoah et les headers compacts optimisent l’usage mémoire et la réactivité sous charge.

Migration & support

• En tant que version LTS, Java 25 bénéficiera de mises à jour de sécurité et de performance au moins jusqu’en 2028.
• Le support du port 32 bits x86 est supprimé, ce qui peut poser problème pour des environnements extrêmement anciens.

Cas d’usage & recommandations

Applications d’IA / calcul intensif : utilisez le Vector API, l’étranglement du CPU profiling, et la capacité à intégrer des patterns primitifs pour rendre plus compact le code de traitement.

Microservices / environnements serverless : le profiling AOT offre un boost au démarrage, améliorant les performances globales.

Systèmes exigeants en latence : les optimisations mémoire (headers compacts) et le mode générational de Shenandoah contribuent à une latence plus stable.

Équipes de développement : adopter les nouveautés (par exemple Flexible Constructor Bodies) peut réduire le temps passé à écrire du code “plombé”.

L’avis de Quentin, Ingénieur Études & Dev chez Elosi

« On a ici affaire à une version très riche, cherchant à améliorer la qualité de vie des développeurs, que ça soit grâce à des fonctionnalités preview ou des changements plus axés sur l’accessibilité du langage. Sur le principe, tous ces changements sont de bonnes améliorations ! Il revient maintenant aux développeurs d’utiliser toutes ces nouveautés à bon escient et de continuer à respecter les bonnes pratiques (ou de les créer si elles n’existent pas encore).

C’est une version LTS stratégique : son adoption judicieuse peut offrir des gains mesurables (performance, maintenance, productivité), tout en renforçant la pérennité des architectures Java.
Cependant, selon moi, certaines nouveautés ne sont pas des avancées, au contraire… Par exemple, l’import de module entier en une ligne peut faciliter la vie sur un projet démo ou sur un projet où l’on cherche davantage le résultat que la performance. Mais dans un projet où la performance est un sujet à part entière, importer un module entier pour deux méthodes est une mauvaise pratique. Montrer ce genre de fonctionnalités à un débutant est pour moi une faute.

On peut citer la même chose pour ce qui est du « Compact Source Files & Instance Main Methods ». »

Quentin V., Ingénieur Études & Dev chez Elosi