Kotlin Academy · Leçon

Projection étoilée et utilisation de *

Appliquez la projection étoilée aux types génériques inconnus et comprenez ses limites.

Leçon 3 sur 413 étapes

Projection étoilée et utilisation de * est une leçon Kotlin Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Kotlin Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Kotlin Academy comprend 4 leçons au total.

Qu’est-ce que la projection étoilée ?

La projection étoilée (*) est la manière dont Kotlin indique « un type générique dont l’argument de type est inconnu ». C’est l’équivalent sûr du type brut de Java ou du caractère générique non borné <?>.

fun printList(list: List<*>) {
    for (item in list) println(item)
}
fun main() {
    printList(listOf(1, 2, 3))
    printList(listOf("a", "b"))
    printList(listOf(true, 42, "mixed"))
}

Lecture à partir de types avec projection étoilée

À partir d’une List<*>, vous pouvez lire les éléments comme des Any?. Vous ne pouvez pas ajouter d’éléments, car le type réel est inconnu.

fun process(list: List<*>) {
    val first: Any? = list.firstOrNull()
    println("First: $first, Size: ${list.size}")
    // list.add("x") // compile error: can't write to List<*>
}
fun main() {
    process(listOf(10, 20, 30))
}

Projection étoilée ou out Any

List<*> et List<out Any?> sont équivalentes. La projection étoilée est une notation abrégée de la projection covariante avec la borne supérieure.

fun sumStars(list: List<*>): Int = list.size
fun sumOut(list: List<out Any?>): Int = list.size
fun main() {
    val l = listOf(1, "two", true)
    println(sumStars(l))  // 3
    println(sumOut(l))    // 3
}

Projection étoilée dans les paramètres de fonction

Utilisez * dans les signatures de fonction lorsque vous devez accepter n’importe quelle variante générique, mais appeler uniquement des méthodes qui ne nécessitent pas de connaître T.

fun containerInfo(map: Map<*, *>): String {
    return "keys=${map.keys.size}, values=${map.values.size}"
}
fun main() {
    val m = mapOf(1 to "one", 2 to "two")
    println(containerInfo(m))
}

Projection étoilée avec MutableList

Pour une MutableList<*>, vous pouvez lire les éléments comme des Any?, mais vous ne pouvez absolument pas écrire dedans : le compilateur l’interdit.

fun clearFirstElement(list: MutableList<*>) {
    if (list.isNotEmpty()) {
        list.removeAt(0)  // OK: remove by index doesn't need T
        // list.add("x") // Error: can't write unknown type
    }
}
fun main() {
    val m = mutableListOf(1, 2, 3)
    clearFirstElement(m)
    println(m) // [2, 3]
}

Classe avec projection étoilée

Lors de la vérification à l’exécution du type d’une classe générique, utilisez la projection étoilée, car les arguments de type sont effacés.

fun isListOfSomething(obj: Any): Boolean {
    return obj is List<*>  // OK with star
    // obj is List<String> // Warning: cannot check erased type
}
fun main() {
    println(isListOfSomething(listOf(1, 2)))  // true
    println(isListOfSomething("not a list"))  // false
}

Plusieurs paramètres avec projection étoilée

Une fonction peut avoir plusieurs paramètres utilisant la projection étoilée lorsqu’elle manipule des paires ou des tables associatives dont les types sont inconnus.

fun describeMap(map: Map<*, *>) {
    map.forEach { (k, v) ->
        println("${k?.javaClass?.simpleName} -> ${v?.javaClass?.simpleName}")
    }
}
fun main() {
    describeMap(mapOf("key" to 42, 1 to true))
}

Quand NE PAS utiliser la projection étoilée

Évitez la projection étoilée lorsque vous devez écrire dans une collection ou lorsque vous pouvez utiliser un paramètre de type borné : ce dernier fournit davantage d’informations.

// Bad: loses type information
fun addToStar(list: MutableList<*>, item: Any?) {
    // list.add(item) // compile error
}
// Better: use bounded type parameter
fun <T : Any> addTyped(list: MutableList<T>, item: T) {
    list.add(item)
}
fun main() {
    val l = mutableListOf("a")
    addTyped(l, "b")
    println(l)
}

Vérifications de type et conversions avec projection étoilée

Utilisez la projection étoilée pour effectuer des vérifications instanceof sur des classes génériques, puis convertissez le type en un type précis pour le traitement réel.

fun handleResponse(response: Any) {
    if (response is List<*>) {
        val list = response as List<*>
        println("List with ${list.size} elements")
        val first = list.firstOrNull()
        if (first is String) println("First string: $first")
    }
}
fun main() {
    handleResponse(listOf("hello", "world"))
    handleResponse(42)
}

Pratique : répartiteur d’événements génériques

Un répartiteur qui accepte n’importe quel Handler<*>, mais répartit les événements typés en toute sécurité.

interface Handler<in T> { fun handle(event: T) }
class LogHandler : Handler<Any> {
    override fun handle(event: Any) = println("Event: $event")
}
fun dispatch(handler: Handler<*>, event: Any) {
    @Suppress("UNCHECKED_CAST")
    (handler as Handler<Any>).handle(event)
}
fun main() {
    dispatch(LogHandler(), "click")
    dispatch(LogHandler(), 42)
}

Projection étoilée dans les contextes reified

La projection étoilée est particulièrement courante dans le code de réflexion et de sérialisation, où le type à l’exécution est inspecté via KClass<*>.

fun printClassName(klass: kotlin.reflect.KClass<*>) {
    println(klass.simpleName)
}
fun main() {
    printClassName(String::class)     // String
    printClassName(List::class)       // List
    printClassName(Int::class)        // Int
}

Vérification rapide

Quel type obtenez-vous lors de la lecture d’une List<*> ?

Récapitulatif

La projection étoilée (*) accepte toute variante générique pour un accès en lecture seule. Utilisez-la pour les vérifications de type, les utilitaires génériques et la réflexion. Évitez-la lorsque vous devez écrire dans une collection ou lorsqu’un paramètre de type borné offre une meilleure sûreté de typage.

Gratuit pour commencer

Apprends Kotlin avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
51
Leçons
203

Questions Fréquemment Posées

La leçon « Projection étoilée et utilisation de * » est-elle gratuite ?

Oui — le texte complet de « Projection étoilée et utilisation de * » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Kotlin Academy, passe à CoddyKit PRO. Le cours Kotlin Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Projection étoilée et utilisation de * » ?

Appliquez la projection étoilée aux types génériques inconnus et comprenez ses limites. Tu pratiques Kotlin Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Kotlin Academy ?

Aucune expérience préalable n'est requise. Kotlin Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Projection étoilée et utilisation de * » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Kotlin Academy ?

Oui. Chaque leçon Kotlin Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Fonctions génériques et contraintes de types avec where
  2. Variance au site de déclaration : in et out
  3. Projection étoilée et utilisation de *
  4. Effacement des types et paramètres de types reified
← Retour à Kotlin Academy