Méthodes statiques en Kotlin : comment un développeur Java peut s'y retrouver dans le monde des object et companion
\n\nSi vous programmez en Java et commencez tout juste à apprendre Kotlin, vous vous êtes sûrement demandé : "Où est donc passé static ?". En Java, nous avons l'habitude d'écrire public static void main() ou MathUtils.max() — c'est pratique, simple et ne nécessite pas de création d'objet. Mais en Kotlin, le mot-clé static n'existe pas. Pas du tout. Vraiment.
Ne paniquez pas. Les développeurs de Kotlin ne sont pas devenus fous — ils ont simplement décidé que les méthodes statiques pouvaient être implémentées de manière plus élégante, sans état global et avec une architecture plus claire. Dans cet article, nous allons passer en revue toutes les façons de remplacer Java static en Kotlin : des simples fonctions au niveau du package au puissant companion object. Vous apprendrez quand utiliser quoi, et vous verrez des exemples de code concrets.
C'est parti ! 🚀
\n\n\n\n
Pourquoi Kotlin n'a-t-il pas de static ? (et c'est une bonne chose)
\n\nEn Java, static est essentiellement une variable ou une méthode globale, liée à la classe et non à une instance. C'est pratique pour les utilitaires, mais cela viole les principes de la POO : les membres statiques ne peuvent pas être redéfinis, ils sont difficiles à tester et créent des couplages forts.
Kotlin encourage une approche plus propre : les fonctions et propriétés peuvent exister au niveau du package (sans classe du tout !) ou être organisées en singletons object. Et si vous avez besoin de lier une méthode à une classe (comme en Java), utilisez companion object. Examinons chaque option.
\n\n
Méthode 1 : Fonctions au niveau du package (la plus simple)
\n\nEn Kotlin, vous pouvez déclarer une fonction ou une propriété simplement dans un fichier, en dehors de toute classe. C'est l'équivalent d'une méthode statique en Java, mais sans la surcharge d'une classe utilitaire.
\n\nExemple :
\n\n// Fichier : MathUtils.kt\npackage com.example.utils\n\nfun max(a: Int, b: Int): Int {\n return if (a > b) a else b\n}\n\nval PI = 3.14159 // constante au niveau du package\n\nCette fonction peut maintenant être appelée de n'importe où (après import) :
\n\nimport com.example.utils.max\nimport com.example.utils.PI\n\nfun main() {\n println(max(10, 20)) // 20\n println(PI) // 3.14159\n}\n\nQuand l'utiliser : pour des fonctions utilitaires simples et des constantes qui ne nécessitent pas d'être regroupées dans une classe. C'est le moyen le plus simple d'obtenir un comportement "statique".
\n\n\n\n
Méthode 2 : Singleton Object (pour un groupe de fonctions liées)
\n\nSi vous avez besoin de regrouper plusieurs méthodes statiques ensemble (comme MathUtils en Java), utilisez object. C'est un singleton — une instance unique créée automatiquement lors de la première utilisation.
Exemple :
\n\nobject StringUtils {\n fun isEmpty(str: String?): Boolean {\n return str.isNullOrEmpty()\n }\n\n fun capitalizeFirst(str: String): String {\n return str.replaceFirstChar { it.uppercase() }\n }\n\n const val EMPTY_STRING = ""\n}\n\nUtilisation :
\n\nfun main() {\n println(StringUtils.isEmpty(null)) // true\n println(StringUtils.capitalizeFirst("kotlin")) // Kotlin\n println(StringUtils.EMPTY_STRING) // ""\n}\n\nImportant : object est une classe à part entière. Elle peut implémenter des interfaces, avoir des initialisateurs et même hériter d'autres classes. Mais elle ne peut pas avoir de constructeurs (sauf privé).
\n\n
Méthode 3 : Companion object (pour les méthodes liées à une classe)
\n\nC'est l'équivalent le plus proche de Java static à l'intérieur d'une classe. companion object est un objet compagnon qui vit à l'intérieur de la classe. Ses méthodes et propriétés sont appelées via le nom de la classe, comme des méthodes statiques.
Exemple :
\n\nclass User(val name: String, val age: Int) {\n companion object {\n fun createAnonymous(): User {\n return User(\"Anonyme\", 0)\n }\n\n const val DEFAULT_NAME = \"Invité\"\n }\n}\n\nUtilisation :
\n\nfun main() {\n val anonymousUser = User.createAnonymous()\n println(User.DEFAULT_NAME) // Invité\n}\n\nQuand l'utiliser : lorsque vous avez besoin de méthodes ou de propriétés qui sont logiquement liées à une classe spécifique, comme des méthodes d'usine (factory methods) ou des constantes de classe.
\n\n