Kotlin const vs val : quelle est la différence et que choisir ?
\n\nVous écrivez du code en Kotlin et vous vous demandez soudainement : « Mais quelle est la différence entre const et val ? Les deux sont censés être immuables, non ? ». Excellente question ! Ce point déroute même les développeurs expérimentés qui passent de Java ou d'autres langages. Il n'est pas étonnant que sur Stack Overflow, le sujet « What is the difference between "const" and "val"? » cumule des milliers de vues. Aujourd'hui, nous allons clarifier ce sujet une fois pour toutes, décomposer la théorie et l'étayer avec des exemples de code concrets.
Prêts ? C'est parti !
\n\nPetit rappel : qu'est-ce que val ?
\n\nCommençons par le plus simple. val (du mot value — valeur) est une référence immuable. Vous pouvez lui attribuer une valeur une seule fois et ne plus jamais la modifier. Cela vous semble familier ? Oui, c'est l'équivalent de final en Java ou de readonly en C#.
val name: String = "Alice"\nname = "Bob" // Erreur de compilation ! Val cannot be reassigned\n\nMais il y a une nuance importante : val garantit que la référence ne changera pas, mais ne garantit pas l'immuabilité de l'objet lui-même. Si vous utilisez val avec une liste mutable (MutableList), vous pouvez toujours ajouter et supprimer des éléments.
val numbers = mutableListOf(1, 2, 3)\nnumbers.add(4) // Fonctionne !\n// numbers = mutableListOf(5, 6) // Erreur ! Impossible de réaffecter la référence\n\nval peut être initialisé soit lors de la déclaration, soit plus tard dans le code (par exemple, dans le constructeur ou un bloc init). Sa valeur est calculée pendant l'exécution du programme (runtime).
Et qu'est-ce que const ? Le gardien strict du temps de compilation
\n\nconst est le frère plus strict de val. Il est également immuable, mais avec un super-pouvoir : la valeur doit être connue au moment de la compilation (compile-time). En d'autres termes, c'est une vraie constante que le compilateur peut intégrer directement dans le code, comme une constante intégrée.
const a des règles strictes :
- \n
- Il ne peut être déclaré qu'au niveau du fichier (en dehors d'une classe) ou à l'intérieur d'un
object/companion object. \n - Il doit être d'un type primitif ou de type
String. \n - Il ne peut pas être le résultat d'un appel de fonction ou d'un calcul — seulement un littéral ou une autre constante. \n
// Correct\nconst val PI = 3.14159\nconst val APP_NAME = "MyApp"\n\n// Incorrect\nconst val currentTime = System.currentTimeMillis() // Erreur ! Valeur inconnue au moment de la compilation\nconst val userName = getName() // Erreur ! Appel de fonction non autorisé\n\nPrincipales différences : const vs val dans un tableau
\n\nPour plus de clarté, voici un tableau comparatif :
\n\n| Critère | \nconst val | \nval | \n
|---|---|---|
| Moment d'initialisation | \nAu moment de la compilation | \nAu moment de l'exécution | \n
| Où peut-on déclarer | \nNiveau supérieur, object, companion object | \nN'importe où (dans une classe, une fonction, un constructeur) | \n
| Types de données | \nUniquement les primitifs et String | \nTous les types (y compris les objets, les listes) | \n
| Performance | \nMaximale (inlining) | \nStandard | \n
| Utilisation dans les annotations | \nOui | \nNon | \n
Exemple pratique : annotations et performance
\n\nL'une des