0Pricing
Kotlin Academy · Aula

Projeção estrela e quando usar *

Aplique a projeção estrela a tipos genéricos desconhecidos e entenda suas limitações.

Projeção estrela e quando usar * é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.

O que é a projeção estrela?

A projeção estrela (*) é a forma do Kotlin de dizer "um tipo genérico com um argumento de tipo desconhecido". Ela é o equivalente seguro do tipo bruto do Java ou do curinga sem limite <?>.

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"))
}

Leitura de tipos com projeção estrela

A partir de uma List<*>, você pode ler os elementos como Any?. Não é possível adicionar elementos porque o tipo real é desconhecido.

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))
}

Projeção estrela versus out Any

List<*> e List<out Any?> são equivalentes. A projeção estrela é uma forma abreviada da projeção covariante com o limite superior.

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
}

Projeção estrela nos parâmetros de funções

Use * nas assinaturas de funções quando precisar aceitar qualquer variante genérica, mas só chamar métodos que não exijam conhecer 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))
}

Projeção estrela com MutableList

Para MutableList<*>, você pode ler como Any?, mas não pode escrever de forma alguma — o compilador impede isso.

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 com projeção estrela

Ao verificar em tempo de execução o tipo de uma classe genérica, use a projeção estrela porque os argumentos de tipo são apagados.

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
}

Vários parâmetros com projeção estrela

Uma função pode ter vários parâmetros com projeção estrela ao trabalhar com pares ou mapas de tipos desconhecidos.

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))
}

Quando NOT usar a projeção estrela

Evite a projeção estrela quando precisar escrever em uma coleção ou quando puder usar um parâmetro de tipo limitado — o tipo limitado fornece mais informações.

// 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)
}

Projeção estrela com verificações de tipo e conversões

Use a projeção estrela para realizar verificações instanceof em classes genéricas e depois converter para um tipo específico para o trabalho efetivo.

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)
}

Prática: distribuidor genérico de eventos

Um distribuidor que aceita qualquer Handler<*>, mas distribui eventos tipados com segurança.

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)
}

Projeção estrela em contextos reificados

A projeção estrela é especialmente comum em código de reflexão e serialização, no qual o tipo em tempo de execução é inspecionado por meio de KClass<*>.

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

Verificação rápida

Que tipo você obtém ao ler de uma List<*>?

Revisão

A projeção estrela (*) aceita qualquer variante genérica para acesso somente de leitura. Use-a para verificações de tipo, utilitários genéricos e reflexão. Evite-a quando precisar escrever em uma coleção ou quando um parâmetro de tipo limitado oferecer mais segurança de tipos.

Perguntas Frequentes

A aula “Projeção estrela e quando usar *” é grátis?

Sim — o texto completo de “Projeção estrela e quando usar *” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.

O que vou aprender em “Projeção estrela e quando usar *”?

Aplique a projeção estrela a tipos genéricos desconhecidos e entenda suas limitações. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Kotlin Academy?

Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Projeção estrela e quando usar *”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Kotlin Academy?

Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Funções genéricas e restrições de tipos com where
  2. Variância no local da declaração: in e out
  3. Projeção estrela e quando usar *
  4. Apagamento de tipos e parâmetros de tipo reified
← Voltar para Kotlin Academy