O que é reified em Kotlin?

A palavra-chave reified permite acessar informações de tipo genérico em tempo de execução. Normalmente, por causa do type erasure da JVM, tipos genéricos são apagados após a compilação. Com reified, o Kotlin mantém essa informação disponível.

Para usar reified, a função precisa ser inline. As duas coisas andam juntas.

O problema sem reified

// Isso NÃO funciona:
fun <T> ehDoTipo(valor: Any): Boolean {
    // return valor is T  // Erro! Não dá pra checar tipo genérico
    return false
}

Na JVM, o tipo T é apagado em tempo de execução. O compilador não sabe qual tipo é T quando o código roda.

A solução com reified

inline fun <reified T> ehDoTipo(valor: Any): Boolean {
    return valor is T
}

fun main() {
    println(ehDoTipo<String>("Kotlin"))  // true
    println(ehDoTipo<Int>("Kotlin"))     // false
    println(ehDoTipo<Int>(42))           // true
}

Com reified, o tipo T é conhecido em tempo de execução. Você pode usar is T, T::class e até criar instâncias (com reflexão).

Exemplo prático: parsing de JSON

inline fun <reified T> parsear(json: String): T {
    println("Parseando para ${T::class.simpleName}")
    // Aqui você usaria uma biblioteca como Gson ou Moshi
    // return Gson().fromJson(json, T::class.java)
    throw NotImplementedError("Exemplo simplificado")
}

Sem reified, seria necessário passar Class<T> como parâmetro extra. Com reified, a informação de tipo já tá disponível.

Filtrando por tipo em coleções

inline fun <reified T> List<Any>.filtrarPorTipo(): List<T> {
    return this.filterIsInstance<T>()
}

fun main() {
    val mistura = listOf(1, "Kotlin", 2.5, "Brasil", 3, true)

    val strings = mistura.filtrarPorTipo<String>()
    println(strings) // [Kotlin, Brasil]

    val inteiros = mistura.filtrarPorTipo<Int>()
    println(inteiros) // [1, 3]
}

Limitações

  • Só funciona com funções inline
  • Não pode ser usado em classes
  • Não pode ser usado com parâmetros noinline

reified é uma ferramenta que resolve elegantemente um problema chato da JVM. Sempre que precisar acessar o tipo genérico em runtime, essa é a saída.