Présentation

Java 17 a ajouté les classes scellées, une construction qui contraint les sous‑types d’une interface ou d’une classe de base à être déclarés explicitement. L’exemple du blog montre une interface SealedType contenant deux records TypeA et TypeB. Le code source fourni illustre la syntaxe public sealed interface … { … } et la méthode of qui crée l’une des implémentations à partir d’une chaîne.

Mécanisme d’exhaustivité

Lorsque la variable val de type SealedType est utilisée dans une expression switch, le compilateur connaît l’ensemble exact des implémentations autorisées. Ainsi le fragment

switch (val) { case SealedType.TypeA() -> "A"; case SealedType.TypeB() -> "B"; }
ne nécessite aucune clause default. Si une implémentation est omise, la compilation échoue, ce qui garantit que chaque cas est traité.

Conséquences sur les API publiques

Le même mécanisme introduit un nouveau type de rupture : ajouter un sous‑type, par exemple TypeC, modifie la liste des cas possibles. Le code

public sealed interface SealedType { record TypeA() implements SealedType {} record TypeB() implements SealedType {} record TypeC() implements SealedType {} }
compile sans problème, mais tout client qui ne recompilé pas son switch déclenchera une java.lang.MatchException à l’exécution, comme le montre la sortie « Exception in thread "main" java.lang.MatchException ». Cette situation apparaît uniquement en compilation séparée, où le compilateur ne peut pas vérifier la couverture exhaustive du client.

Limites et bonnes pratiques

En pratique, les classes scellées offrent le meilleur rendement lorsqu’elles restent confinées à l’intérieur d’un même module ou d’une même bibliothèque, où toutes les unités sont recompilées simultanément. Dans ce contexte, l’exhaustivité du switch améliore la sûreté du code sans introduire de risques de rupture. En revanche, exposer un type scellé dans une API publique oblige les mainteneurs à considérer chaque nouveau sous‑type comme une rupture majeure, souvent justifiant un changement de version majeur selon SemVer. L’auteur du billet recommande donc de réserver les classes scellées aux implémentations internes et d’éviter leur utilisation comme point d’extension d’une bibliothèque tierce.