Java 25 est devenu GA (General Availability) le 16 septembre 2025, marquant la première version LTS (Long-Term Support) depuis Java 21 (sorti en septembre 2023). Oracle s'engage sur un support de 8 ans minimum, ce qui en fait la cible de migration évidente pour toutes les équipes encore sur Java 17 ou 21. En mars 2026, l'adoption s'accélère : les principaux frameworks (Spring Boot, Quarkus, Micronaut) supportent pleinement Java 25, et les cloud providers proposent des runtimes stables.
Ce guide couvre les 18 JEPs (JDK Enhancement Proposals) de Java 25 avec un focus sur ce qui change concrètement pour un développeur backend au quotidien.
Pourquoi migrer maintenant ?
Avant de détailler les fonctionnalités, la question légitime : Java 21 était déjà LTS, pourquoi migrer vers 25 ?
Fin du support commercial Java 21 pour certains distributeurs approche à horizon 2026-2027. Java 25 offre une garantie jusqu'à 2033+ avec la plupart des vendeurs.
Performance réelle mesurée : les équipes early adopters rapportent des gains de démarrage de 15 à 30% avec l'AOT profiling, et des réductions mémoire de 10 à 20% grâce aux optimisations du GC ZGC.
Syntaxe modernisée : les fonctionnalités en preview depuis Java 21-24 sont désormais finalisées et stables. On peut les utiliser en production sans flag --enable-preview.
Pattern Matching : enfin finalisé
Le pattern matching pour switch et instanceof sort de preview en Java 25. Ce qui était expérimental depuis Java 16 est maintenant partie intégrante du langage.
Switch avec pattern matching
// Java 21 (preview, nécessitait --enable-preview)
// Java 25 (stable, aucun flag requis)
Object obj = getPayload();
String description = switch (obj) {
case Integer i when i > 0 -> "Entier positif : " + i;
case Integer i -> "Entier négatif ou zéro : " + i;
case String s -> "Chaîne de longueur " + s.length();
case null -> "Valeur nulle";
default -> "Type inconnu : " + obj.getClass().getSimpleName();
};
Deconstruction de records dans les switch
record Point(int x, int y) {}
record Circle(Point center, double radius) {}
Shape shape = new Circle(new Point(0, 0), 5.0);
String info = switch (shape) {
case Circle(Point(int x, int y), double r) ->
"Cercle centré en (%d, %d) rayon %.1f".formatted(x, y, r);
case Rectangle(int w, int h) ->
"Rectangle %dx%d".formatted(w, h);
};
La deconstruction nested est stable en Java 25, ce qui ouvre des patterns très expressifs pour traiter des hiérarchies de types complexes (AST, réponses d'API, events métier).
Compact Source Files
L'une des JEPs les plus discutées : Java 25 introduit les compact source files, permettant d'écrire un programme Java valide sans déclarer de classe explicitement.
// HelloWorld.java — programme Java 25 valide, sans classe
void main() {
System.out.println("Hello, Java 25!");
}
// script-calcul.java — calculs simples sans boilerplate
import java.util.List;
void main() {
var prix = List.of(12.5, 8.0, 45.0, 3.2);
double total = prix.stream().mapToDouble(Double::doubleValue).sum();
System.out.printf("Total : %.2f€%n", total);
}
Cette feature cible principalement les scripts, les cours d'apprentissage et les petits utilitaires. Pour du code de production, les classes restent la norme — mais c'est un signal clair qu'Oracle veut réduire la friction pour les nouveaux développeurs.
Module Import Declarations
Importer tous les packages d'un module en une seule ligne :
// Avant Java 25
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.stream.Collectors;
// Java 25 — importe tout java.base
import module java.base;
// Ou pour des modules tiers
import module com.fasterxml.jackson.databind;
Pour les développeurs Spring Boot, cette simplification est appréciable dans les classes de service qui importent de nombreuses dépendances utilitaires.
AOT Method Profiling
La JEP la plus impactante pour la performance en production. Java 25 introduit le profilage de méthodes Ahead-of-Time : la JVM peut sauvegarder un profil d'exécution entre les redémarrages et l'utiliser pour optimiser la compilation JIT dès le démarrage.
# Étape 1 : créer un profil lors d'un démarrage normal
java -XX:+AOTMethodProfiling -XX:AOTProfilingFile=app.aprof -jar app.jar
# Étape 2 : démarrages suivants utilisent le profil
java -XX:AOTMethodProfiling=app.aprof -jar app.jar
Résultats mesurés sur des applications Spring Boot :
- Temps au premier appel HTTP : -25 à -40%
- Warm-up duration : réduit de 60%
- Throughput peak atteint 2x plus vite
Pour des déploiements Kubernetes avec rolling updates fréquents, l'impact sur l'expérience utilisateur des premiers instants après démarrage est significatif. La commande peut être combinée avec GraalVM Native Image pour les cas où le démarrage ultra-rapide est critique.
Flexible Constructor Bodies
Une simplification syntaxique qui facilite la validation dans les constructeurs :
public class Connection {
private final String host;
private final int port;
public Connection(String host, int port) {
// Java 25 : instructions avant super() ou this() autorisées
if (host == null || host.isBlank()) {
throw new IllegalArgumentException("Host requis");
}
if (port < 1 || port > 65535) {
throw new IllegalArgumentException("Port invalide : " + port);
}
this.host = host;
this.port = port;
}
}
Avant Java 25, placer du code avant super() ou this() était interdit, forçant des workarounds verbeux (méthodes statiques de validation, factory methods). Cette restriction est levée.
ZGC et G1GC : optimisations mémoire
Java 25 apporte des améliorations substantielles aux deux GC principaux :
ZGC (Generational ZGC maintenant par défaut) :
- Réduction de 10 à 20% de la consommation mémoire pour les applications à longue durée de vie
- Pauses GC inférieures à 1ms même avec des heaps de plusieurs dizaines de Go
- Meilleure gestion des régions compactes pour les microservices
G1GC :
- Amélioration du throughput sur les workloads CPU-intensifs
- Mixed collections plus intelligentes réduisant la fragmentation
Pour les applications Spring Boot déployées sur Kubernetes avec des limites mémoire strictes, activer -XX:+UseZGC en Java 25 est un gain quasi-systématique.
Checklist de migration depuis Java 21
Étape 1 — Identifier les incompatibilités
# Outil officiel d'analyse de compatibilité
java --version # Vérifier Java 25
jdeps --jdk-internals -cp target/app.jar
Étape 2 — Mettre à jour le pom.xml
<properties>
<java.version>25</java.version>
<maven.compiler.source>25</maven.compiler.source>
<maven.compiler.target>25</maven.compiler.target>
</properties>
Étape 3 — Activer l'AOT profiling en staging
java -XX:+AOTMethodProfiling -XX:AOTProfilingFile=profile.aprof -jar app.jar
Étape 4 — Retirer les flags preview obsolètes
Si votre build utilisait --enable-preview pour le pattern matching ou les records deconstruction, ces flags ne sont plus nécessaires en Java 25.
Étape 5 — Tester avec le nouveau GC
java -XX:+UseZGC -jar app.jar
Compatibilité avec l'écosystème Spring
Spring Boot 3.4+ supporte officiellement Java 25 depuis décembre 2025. La compatibilité couvre :
- Spring Framework 6.2
- Spring Security 6.4
- Spring Data JPA avec Hibernate 7.0
- Spring AI (support natif des Virtual Threads de Java 21 + optimisations Java 25)
Pour les détails de migration Spring Boot spécifiques, consultez notre guide [Spring Boot 4 : les breaking changes](/spring-boot-4-breaking-changes/) et le tutoriel [Spring Boot sur GraalVM Native](/spring-boot-graalvm-native/) qui se combinent naturellement avec Java 25.
Conclusion
Java 25 LTS consolide 4 ans d'améliorations depuis Java 21 en les passant en status stable. Le pattern matching finalisé, l'AOT profiling et les optimisations GC sont les trois raisons principales de migrer pour des équipes production. La migration depuis Java 21 est douce — peu de breaking changes — et les gains de performance justifient l'investissement, particulièrement pour des déploiements Kubernetes à forte charge.