Reified em Kotlin: a magia dos genéricos para iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

O que é reified em Kotlin e por que é "mágica"?

\n

Se você já programou em Java, certamente já se deparou com Type Erasure — o apagamento de tipos em tempo de execução. Em Java (e em Kotlin por padrão), a informação sobre o tipo dentro de genéricos está disponível apenas em tempo de compilação, e em tempo de execução — desaparece. Isso significa que você não pode escrever if (value is T) ou T::class dentro de uma função comum, porque T em tempo de execução é apenas Object.

\n

Mas o Kotlin foi além. A palavra-chave reified (do inglês "reificado") permite "reviver" o tipo dentro de uma função inline. Graças ao reified, você pode fazer o que parecia impossível em Java: verificar o tipo, obter KClass, criar instâncias e até trabalhar com reflexão — tudo em tempo de execução.

\n

Neste artigo, vamos analisar como o reified funciona, com exemplos reais que você pode aplicar imediatamente. Vamos lá!

\n\n

Problema: Type Erasure em ação

\n

Imagine: você está escrevendo uma função que deve verificar se um objeto é uma string. Tentativa ingênua:

\n
fun <T> isString(value: Any): Boolean {\n    return value is T // Erro de compilação!\n}
\n

O compilador emitirá um erro: "Cannot check for instance of erased type: T". Por quê? Porque em tempo de execução, a JVM não sabe o que é T. Para ela, T é apenas Object.

\n

O mesmo acontece ao obter a classe: T::class dentro de uma função comum também não funciona. Isso é o Type Erasure — a principal dor de cabeça dos desenvolvedores Java.

\n\n

Solução: reified + inline

\n

Kotlin oferece uma saída elegante. Para "lembrar" o tipo em tempo de execução, você precisa tornar a função inline e marcar o parâmetro de tipo com a palavra-chave reified:

\n
inline fun <reified T> isString(value: Any): Boolean {\n    return value is T // Agora funciona!\n}
\n

Agora você pode chamar:

\n
println(isString<String>("Hello")) // true\nprintln(isString<Int>("Hello"))    // false
\n

Como isso funciona? Quando você marca uma função como inline, o compilador insere seu código diretamente no local da chamada. E reified faz o compilador substituir o tipo concreto (por exemplo, String) no lugar de T no código gerado. Como resultado, no bytecode aparece uma verificação explícita value is String.

\n\n

Exemplos práticos de uso do reified

\n

Vamos ver alguns cenários reais onde o reified realmente simplifica a vida.

\n\n

1. Obtendo a classe em tempo de execução

\n

Uma das tarefas mais comuns é obter KClass ou Class a partir do parâmetro de tipo. Sem reified, isso é impossível:

\n
inline fun <reified T> getKClass(): KClass<T> = T::class\n\n// Uso:\nval kClass = getKClass<String>()\nprintln(kClass.simpleName) // String
\n

Isso é especialmente útil ao trabalhar com bibliotecas que exigem reflexão (por exemplo, serialização, ORM, contêineres DI).

\n\n

2. Criando uma instância por tipo

\n

Quer criar um objeto do tipo desejado sem passar um construtor? Fácil:

\n
inline fun <reified T : Any> createInstance(): T {\n    return T::class.createInstance()\n}\n\n// Exemplo:\nval instance = createInstance<StringBuilder>()\ninstance.append("Hello, reified!")
\n

Mas cuidado: createInstance() funciona apenas se a classe tiver um construtor sem parâmetros. Caso contrário, você receberá uma exceção.

\n\n

3. Filtragem por tipo em coleções

\n

Suponha que você tenha uma lista de objetos de diferentes tipos e queira filtrar apenas as strings. Na biblioteca padrão do Kotlin existe filterIsInstance<T>(), mas você pode facilmente escrever sua própria versão:

\n


                
                

Blogs

Book Recommendations