---
title: "Reified em Kotlin: O que É e Como Funciona | Kotlin Brasil"
url: "https://kotlin.dev.br/glossario/reified/"
markdown_url: "https://kotlin.dev.br/glossario/reified.MD"
description: "Descubra o que é reified em Kotlin, como manter informações de tipo genérico em tempo de execução com inline."
date: "2026-02-11"
author: "Karina Melo"
---

# Reified em Kotlin: O que É e Como Funciona | Kotlin Brasil

Descubra o que é reified em Kotlin, como manter informações de tipo genérico em tempo de execução com inline.


## 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

```kotlin
// 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

```kotlin
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

```kotlin
inline fun <reified T> parsear(json: String): T {
    println("Parseando para ${T::class.simpleName}")
    // Aqui voce 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

```kotlin
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]
}
```

### Criando instâncias com reified

Com `reified` você pode acessar o construtor de um tipo genérico via reflexão, algo impossível sem essa palavra-chave:

```kotlin
inline fun <reified T : Any> criarInstancia(): T {
    val construtor = T::class.constructors.firstOrNull { it.parameters.isEmpty() }
        ?: throw IllegalArgumentException("${T::class.simpleName} nao tem construtor sem argumentos")
    return construtor.call()
}

class Motor {
    val tipo = "V8"
    override fun toString() = "Motor(tipo=$tipo)"
}

class Roda {
    val aro = 17
    override fun toString() = "Roda(aro=$aro)"
}

fun main() {
    val motor = criarInstancia<Motor>()
    val roda = criarInstancia<Roda>()
    println(motor) // Motor(tipo=V8)
    println(roda)  // Roda(aro=17)
}
```

### Reified com funções de extensão

A combinação de `reified` com funções de extensão cria APIs muito elegantes. Veja um exemplo inspirado em frameworks de injeção de dependência:

```kotlin
class Container {
    private val servicos = mutableMapOf<String, Any>()

    fun registrar(servico: Any) {
        servicos[servico::class.qualifiedName ?: ""] = servico
    }

    inline fun <reified T : Any> obter(): T {
        val chave = T::class.qualifiedName
        return servicos[chave] as? T
            ?: throw IllegalStateException("Serviço ${T::class.simpleName} nao registrado")
    }
}

class BancoDeDados {
    fun consultar(sql: String) = "Resultado de: $sql"
}

class ServicoDeEmail {
    fun enviar(para: String) = println("Email enviado para $para")
}

fun main() {
    val container = Container()
    container.registrar(BancoDeDados())
    container.registrar(ServicoDeEmail())

    val db = container.obter<BancoDeDados>()
    println(db.consultar("SELECT * FROM usuarios"))

    val email = container.obter<ServicoDeEmail>()
    email.enviar("karina@kotlin.dev.br")
}
```

### Limitações

- Só funciona com funções `inline`
- Não pode ser usado em classes
- Não pode ser usado com parâmetros `noinline`
- Não pode ser chamado a partir de código Java (funções inline com reified não são visíveis para Java)
- Funções inline com reified não podem ser armazenadas em variáveis de tipo função

### Casos de Uso no Mundo Real

- **Serialização e desserialização**: bibliotecas como Gson, Moshi e kotlinx.serialization usam reified para determinar o tipo de destino ao converter JSON, XML ou outros formatos em objetos Kotlin.
- **Injeção de dependência**: frameworks como Koin usam `inline fun <reified T> get(): T` para resolver dependências sem passar `Class<T>` explicitamente, tornando a API muito mais limpa.
- **Logging com tipo automático**: criar funções de log que automaticamente incluem o nome da classe sem precisar receber parâmetros adicionais, como `inline fun <reified T> T.logger() = LoggerFactory.getLogger(T::class.java)`.
- **Navegação no Android**: usar reified para criar funções de navegação tipadas, como `inline fun <reified T : Activity> Context.iniciarActivity()`, eliminando a necessidade de passar a classe explicitamente.

### Boas Práticas

- Use `reified` apenas quando realmente precisar acessar o tipo em runtime. Se a lógica não depende de `T::class`, `is T` ou reflexão, não precisa de reified.
- Lembre-se de que funções `inline` com `reified` são copiadas em cada ponto de chamada. Mantenha o corpo da função enxuto para não inflar o bytecode.
- Combine com upper bounds (`<reified T : AlgumaInterface>`) para restringir os tipos aceitos e garantir segurança em tempo de compilação.
- Prefira `reified` a receber `Class<T>` ou `KClass<T>` como parâmetro. A API fica mais limpa e idiomática.
- Documente as restrições de tipo quando usar reified em APIs públicas, já que o compilador nem sempre consegue dar mensagens de erro claras sobre tipos incompatíveis.

### Erros Comuns

- **Esquecer de marcar a função como `inline`**: o compilador vai reclamar, mas a mensagem de erro pode confundir iniciantes. Lembre-se: `reified` exige `inline`, sempre.
- **Criar funções inline muito grandes com reified**: como o corpo da função é copiado em cada chamada, funções longas geram muito bytecode duplicado. Extraia a lógica não-inline para funções auxiliares.
- **Tentar usar reified em parâmetros de classe**: `class Repositorio<reified T>` não funciona. Reified é exclusivo de funções inline. Para classes, passe `KClass<T>` no construtor.
- **Assumir que reified funciona com herança de tipos**: `ehDoTipo<Number>(42)` retorna `false` para `is Number` em alguns cenários com tipos primitivos, porque a JVM trata primitivos de forma especial.
- **Chamar funções reified a partir de Java**: código Java não consegue chamar funções inline com reified. Se sua API precisa ser compatível com Java, forneça uma alternativa que receba `Class<T>`.

### Perguntas Frequentes

**Por que `reified` precisa de `inline`?** Porque o mecanismo funciona substituindo o corpo da função no ponto de chamada. Ao fazer isso, o compilador conhece o tipo concreto usado e pode inserir a informação de tipo diretamente no bytecode gerado.

**Posso usar `reified` com múltiplos parâmetros de tipo?** Sim. Você pode ter vários parâmetros reified na mesma função, como `inline fun <reified A, reified B> converter(valor: A): B`. Cada um será resolvido independentemente.

**Qual a diferença entre `reified` e passar `Class<T>` como parâmetro?** Funcionalmente, o resultado é o mesmo. A diferença é ergonomia: com reified, você escreve `parsear<Usuario>(json)` em vez de `parsear(json, Usuario::class.java)`. O código fica mais limpo e idiomático.

**O `reified` tem impacto na performance?** O impacto é o mesmo do `inline` em geral: o corpo da função é copiado em cada chamada, o que pode aumentar o tamanho do bytecode mas elimina o overhead de chamada de função. Para funções pequenas, o impacto é negligível ou até positivo.

### Termos Relacionados

- [Inline Function](/glossario/inline) — funções que são expandidas no ponto de chamada, requisito para reified
- [Generics](/glossario/generics) — o sistema de tipos genéricos do Kotlin
- [Extension Function](/glossario/extension-function) — funções de extensão que combinam bem com reified
- [Reflection](/glossario/reflection) — reflexão em Kotlin, frequentemente usada junto com reified

`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.
