En Kotlin, classe inline (à partir de Kotlin 1.5 — le terme "classe valeur"), permet de créer des wrappers autour des types avec des coûts minimaux. Lors de la compilation, ces classes sont sous le capot remplacées par leur valeur interne (value) pour éviter les frais de création d'objets.
Limitations et caractéristiques :
=== ne fonctionne pas comme d'habitude).Exemple :
@JvmInline value class UserId(val value: String) fun getUser(id: UserId) { println("Chargement de l'utilisateur avec l'id : ${id.value}") } val id = UserId("XYZ") getUser(id) // Sous le capot, cela fonctionne simplement avec String !
Quand utiliser :
Peut-on hériter de la classe de valeur ou l'utiliser dans une hiérarchie d'interfaces/classes abstraites ?
Réponse : Non, la classe de valeur ne peut pas hériter d'autres classes (à l'exception des interfaces), ne peut pas être ouverte à l'héritage, ne permet pas de bloc init et d'autres champs non statiques. La seule option disponible est d'implémenter des interfaces.
Exemple :
interface Validatable { fun isValid(): Boolean } @JvmInline value class Email(val raw: String) : Validatable { override fun isValid() = raw.contains("@") }
Histoire
Une application Android a soudainement augmenté son temps de démarrage après avoir ajouté des classes de valeur aux paramètres Parcelable : il s'est avéré qu'un @Parcelize incorrect avec une classe de valeur conduisait à un boxing/unboxing à chaque étape de la sérialisation, annulant les avantages de l'inline.
Histoire
Un microservice a commencé à utiliser activement la classe de valeur pour UserId et ProductId pour des raisons de sécurité des types, mais à de nombreux endroits, des fonctions génériques nécessitaient une réflexion qui ne fonctionnait pas avec "l'enveloppe". Les tests unitaires ont commencé à échouer de manière inattendue, des ClassCastException sont apparues.
Histoire
Le code migré de Java a commencé à remplacer des classes de domaine internes par des classes de valeur pour l'optimisation, mais leur utilisation en tant que champs nullable a conduit à des exceptions null pointer inattendues, car la classe de valeur ne peut être null que si la valeur extérieure est également null, ce qui brisait les anciens invariants.