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().

Java — Avant et après les Records
// ❌ 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.

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.

Java
// ❌ 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.

Java
// ❌ 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.

Shell
# 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

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.