En Kotlin, le modificateur const val est utilisé uniquement pour les constantes de compilation au niveau top-level (au niveau du fichier), ou à l'intérieur des objets (object) et des objets compagnons. Les propriétés déclarées comme val à l'intérieur des classes deviennent des propriétés finales normales sans initialisation statique. Une particularité importante : const val ne peut pas être hérité, alors que val peut être redéfini (si autorisé).
Les constantes (const val) ne peuvent pas être abstraites, car elles doivent avoir une valeur au moment de la compilation. Les val normaux permettent de réaliser un modèle de constantes dans les hiérarchies via des propriétés ouvertes, cependant, à l'exécution, elles seront accessibles via un getter, ce qui diffère de la compilation en Java.
open class Base { open val info: String = "base" } class Child : Base() { override val info = "child" } object Constants { const val APPLICATION_NAME = "MyApp" }
Peut-on déclarer
const valdans une interface ou une classe abstraite et ensuite le redéfinir/hériter ?
Non. En Kotlin, il n'est pas possible de déclarer const val à l'intérieur d'une interface ou d'une classe abstraite — cela est autorisé uniquement au niveau des objets (object) et top-level. Il n'existe pas de variables équivalentes de type static final disponibles pour l'héritage.
interface Foo { // const val X = "constant" // erreur de compilation : les 'const val' ne sont autorisées qu'au niveau top-level, dans des objets, ou dans des objets compagnons }
Histoire
L'équipe a tenté de réutiliser des constantes de chaîne via l'héritage d'interface dans plusieurs modules Android, en les déclarant comme
const val— ils ont obtenu une erreur de compilation et ont été contraints de déplacer les constantes au niveau top-level, ce qui a détérioré l'encapsulation.
Histoire
Dans un projet, ils ont transféré tous les champs Java static final dans des champs Kotlin
valdans des classes ouvertes, en s'attendant à un comportement similaire (constante de compilation), mais ils sont devenus des propriétés normales avec getter. En conséquence, le temps d'accès a augmenté, ce qui a eu un impact négatif sur les chemins chauds (hot path) de l'application microservices.
Histoire
Lors de la migration des classes Java de conteneurs de constantes vers Kotlin, les développeurs ont créé des constantes à l'intérieur de l'objet compagnon, mais ont rencontré des problèmes d'accès depuis le code Java : les constantes étaient visibles comme des champs du compagnon lui-même, et non de la classe, ce qui a provoqué de la confusion dans l'API et des bugs supplémentaires d'interopérabilité.