Réflexion et introspection en Kotlin : comment regarder à l'intérieur de votre code
\n\nImaginez que vous êtes un développeur qui écrit du code capable de s'analyser lui-même. Cela ressemble à de la science-fiction ? Dans le monde de Kotlin, c'est une réalité. La réflexion et l'introspection sont ces outils qui transforment votre code d'un simple exécutant en un véritable méta-programmeur. Si vous avez déjà voulu obtenir dynamiquement des informations sur les classes, appeler des méthodes par leur nom ou travailler avec des annotations à l'exécution, cet article est pour vous.
\n\nNous allons voir comment Kotlin, en tant que langage fonctionnant sur la JVM, utilise la réflexion, et comment avec des exemples simples vous pouvez ajouter de la magie à vos projets. C'est parti !
\n\nQu'est-ce que la réflexion et l'introspection ? La différence à connaître
\n\nAvant de plonger dans le code, clarifions les termes. Ces concepts sont souvent confondus, mais il existe une nuance subtile entre eux.
\n\n- \n
- Introspection — c'est la capacité d'un programme à "se regarder lui-même". Vous pouvez obtenir des informations sur la structure des classes : leurs propriétés, méthodes, constructeurs. C'est comme ouvrir le capot d'une voiture et voir ce qu'il y a à l'intérieur. \n
- Réflexion — c'est un outil plus puissant. Vous ne vous contentez pas de regarder, vous modifiez le comportement du programme pendant son exécution. Vous pouvez appeler des méthodes que vous ne connaissiez pas au moment de la compilation, créer des objets à partir du nom textuel d'une classe. \n
En Kotlin, la réflexion est étroitement liée à la réflexion JVM, mais possède ses propres API spécifiques à Kotlin (par exemple, KClass, KFunction). Et oui, pour travailler avec la réflexion, vous devrez ajouter une dépendance dans votre build.gradle.kts :
dependencies {\n implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.22")\n}\n\n\nSans elle, vous ne pourrez utiliser que les fonctionnalités de base, comme javaClass. Mais pour une expérience Kotlin complète, installez la bibliothèque.
KClass : votre principal outil d'introspection
\n\nEn Java, nous sommes habitués à Class<?>. En Kotlin, son équivalent est KClass. C'est le point d'entrée dans le monde de la réflexion. Obtenir un KClass peut se faire de deux manières :
// Méthode 1 : via l'objet de classe\nval myClass: KClass<String> = String::class\n\n// Méthode 2 : via une instance\nval str = "Bonjour, le monde !"\nval classFromInstance: KClass<out String> = str::class\n\n\nVous avez maintenant accès à une multitude d'informations : nom de la classe, package, constructeurs, propriétés, fonctions. Regardons un exemple :
\n\ndata class Utilisateur(val nom: String, val age: Int)\n\nfun main() {\n val kClass = Utilisateur::class\n println("Nom de la classe : ${kClass.simpleName}") // Utilisateur\n println("Package : ${kClass.qualifiedName}") // com.example.Utilisateur\n println("Nombre de propriétés : ${kClass.memberProperties.size}") // 2 (nom, age)\n \n kClass.memberProperties.forEach { prop ->\n println("Propriété : ${prop.name}, type : ${prop.returnType}")\n }\n}\n\n\nC'est de l'introspection pure en Kotlin — nous nous contentons d'observer la structure. Aucune modification de comportement.
\n\nObtenir des informations sur les fonctions et les constructeurs
\n\nParfois, vous avez besoin de connaître les méthodes d'une classe, ou même de les appeler. Pour cela, nous utilisons KFunction.
class Calculatrice {\n fun additionner(a: Int, b: Int): Int = a + b\n fun multiplier(a: Int, b: Int): Int = a * b\n}\n\nfun main() {\n val calcClass = Calculatrice::class\n println("Fonctions de la classe Calculatrice :")\n calcClass.memberFunctions.forEach { func ->\n println(" - ${func.name} (paramètres : ${func.parameters})")\n }\n}\n\n\nLa sortie ressemblera à ceci :
\nFonctions de la classe Calculatrice :\n - additionner (paramètres : [a, b])\n - multiplier (paramètres : [a, b])\n\n\nLa réflexion en action : appeler des méthodes et créer des objets
\n\nEt maintenant, la partie la plus intéressante — la réflexion. Supposons que vous ayez une chaîne de caractères contenant le nom d'une méthode,