Java 17, sortie en septembre 2021, est une version LTS majeure qui standardise plusieurs fonctionnalités très attendues : les Records, les Sealed Classes, le Pattern Matching pour instanceof, et les Text Blocks. C'est la version de référence qui a poussé de nombreuses équipes à abandonner Java 8 et 11.
Java 17 est le minimum requis pour Spring Boot 3.x, Jakarta EE 10 et de nombreux frameworks modernes. C'est la version LTS la plus utilisée en production en 2023-2024.
1. Records — Classes de données immuables
Les Records (JEP 395, stable depuis Java 16) sont des classes déclaratives pour les données immuables. Le compilateur génère automatiquement le constructeur, getters, equals(), hashCode() et toString().
// ❌ Avant — class verbose (souvent remplacée par Lombok)
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) { this.x = x; this.y = y; }
public int x() { return x; }
public int y() { return y; }
// + equals(), hashCode(), toString()...
}
// ✅ Java 17 — Record en une ligne
public record Point(int x, int y) {}
// Utilisation
var p = new Point(3, 4);
p.x(); // 3
p.y(); // 4
// Record avec validation
public record Personne(String nom, int age) {
// Constructeur compact
public Personne {
if (age < 0) throw new IllegalArgumentException("Âge négatif");
nom = nom.trim();
}
// Méthodes supplémentaires autorisées
public String initiales() { return nom.substring(0, 1).toUpperCase(); }
}
// Records dans les streams
record Produit(String nom, double prix) {}
List<Produit> produits = List.of(
new Produit("Java", 0.0),
new Produit("Spring", 0.0)
);
produits.stream()
.map(Produit::nom)
.forEach(System.out::println);
2. Sealed Classes — Hiérarchie contrôlée
Les Sealed Classes (JEP 409) permettent de limiter quelles classes peuvent étendre ou implémenter un type. C'est le fondement du pattern algebraic data type en Java.
// Sealed interface — uniquement ces 3 types autorisés
public sealed interface Forme
permits Cercle, Rectangle, Triangle {}
// Sous-types : final, sealed, ou non-sealed
public record Cercle(double rayon) implements Forme {}
public record Rectangle(double largeur, double hauteur) implements Forme {}
public record Triangle(double base, double hauteur) implements Forme {}
// Sealed class avec héritage
public sealed class Resultat<T>
permits Resultat.Ok, Resultat.Err {
public record Ok<T>(T valeur) extends Resultat<T> {}
public record Err<T>(String msg) extends Resultat<T> {}
}
3. Pattern Matching pour instanceof
Le Pattern Matching pour instanceof (JEP 394, stable Java 16) élimine le cast manuel après un test de type.
// ❌ Avant Java 16 — cast manuel
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// ✅ Java 17 — pattern variable
if (obj instanceof String s) {
System.out.println(s.length());
}
// Avec condition combinée
if (obj instanceof String s && s.length() > 5) {
System.out.println("Long : " + s);
}
// Usage dans une méthode polymorphique
double surface(Forme forme) {
if (forme instanceof Cercle c)
return Math.PI * c.rayon() * c.rayon();
if (forme instanceof Rectangle r)
return r.largeur() * r.hauteur();
if (forme instanceof Triangle t)
return 0.5 * t.base() * t.hauteur();
throw new UnsupportedOperationException();
}
4. Text Blocks — Chaînes multilignes
Les Text Blocks (JEP 378, stable Java 15) facilitent l'écriture de JSON, SQL, HTML et XML inline.
// ❌ Avant — concaténation pénible
String json = "{\n" +
" \"nom\": \"Kriss\",\n" +
" \"role\": \"Développeur\"\n" +
"}";
// ✅ Java 17 — Text Block
String json = """
{
"nom": "Kriss",
"role": "Développeur Full Stack"
}
""";
// SQL lisible
String requete = """
SELECT u.nom, u.email, p.titre
FROM utilisateurs u
JOIN projets p ON p.user_id = u.id
WHERE u.actif = true
AND p.date_creation > ?
ORDER BY u.nom ASC
""";
// Template HTML
String html = """
<div class="card">
<h2>%s</h2>
<p>%s</p>
</div>
""".formatted(titre, description);
5. Strong Encapsulation des internals JDK
Java 17 rend définitive l'encapsulation forte des API internes du JDK. Les accès via réflexion à des classes comme sun.misc.Unsafe nécessitent désormais un flag explicite.
# Si un framework utilise des internals JDK (ex: Hibernate, certaines versions)
java --add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens java.base/java.util=ALL-UNNAMED \
-jar monapp.jar
6. Autres changements notables
- Foreign Function & Memory API (JEP 412) — incubateur pour accéder à la mémoire native sans JNI
- Context-Specific Deserialization Filters (JEP 415) — sécurité renforcée
- Applet API supprimée —
java.applet.Appletretirée définitivement - Security Manager déprécié — prévu pour suppression
- Améliorations de Shenandoah et ZGC — garbage collectors modernes
7. Récapitulatif Java 17
Records
Classes de données immuables en une ligne, sans boilerplate.
Sealed Classes
Hiérarchie de types fermée et contrôlée par le compilateur.
Pattern Matching instanceof
Fin des casts manuels redondants.
Text Blocks
JSON, SQL, HTML inline lisibles et maintenables.
Encapsulation JDK
Accès aux internals restreint, code plus sécurisé.
Base Spring Boot 3
Prérequis pour Spring Boot 3.x, Jakarta EE 10 et les frameworks modernes.