---
title: "Annotation em Kotlin: O que É e Como Funciona | Kotlin Brasil"
url: "https://kotlin.dev.br/glossario/annotation/"
markdown_url: "https://kotlin.dev.br/glossario/annotation.MD"
description: "Aprenda o que são Annotations em Kotlin, como criar e usar anotações para adicionar metadados ao código."
date: "2026-02-12"
author: "Karina Melo"
---

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

Aprenda o que são Annotations em Kotlin, como criar e usar anotações para adicionar metadados ao código.


## O que é Annotation em Kotlin?

Annotations (anotacoes) sao **metadados** que você adiciona ao código para fornecer informações extras ao compilador, a ferramentas de build ou a frameworks em tempo de execução. Elas não mudam o comportamento do código diretamente, mas servem como instrucoes pra quem processa o código.

Se você já usou `@Override` em Java ou `@Composable` no Jetpack Compose, já usou annotations.

Pense em annotations como etiquetas coladas em um produto: a etiqueta não muda o produto em si, mas informa quem o manipula (o caixa, o estoquista, o transportador) sobre como trata-lo. Da mesma forma, annotations informam o compilador, frameworks e ferramentas sobre como processar determinado trecho de código.

### Usando annotations existentes

```kotlin
class Animal {
    @Deprecated("Use falar() no lugar", ReplaceWith("falar()"))
    fun emitirSom() {
        println("Som generico")
    }

    fun falar() {
        println("Som do animal")
    }
}

fun main() {
    val animal = Animal()
    animal.emitirSom()  // Aviso: Deprecated
    animal.falar()
}
```

Annotations comuns do Kotlin:
- `@Deprecated` -- marca algo como obsoleto
- `@Suppress` -- suprime avisos do compilador
- `@JvmStatic` -- gera método estático pra interop com Java
- `@Throws` -- declara exceções pra interop com Java

### Criando suas proprias annotations

```kotlin
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class LogExecucao(val nivel: String = "INFO")

@LogExecucao(nivel = "DEBUG")
fun processarDados() {
    println("Processando...")
}
```

Os meta-annotations controlam o comportamento:
- `@Target` -- onde pode ser aplicada (classe, função, propriedade, etc.)
- `@Retention` -- se fica disponivel em runtime, só no binario, ou só no código fonte

### Exemplo prático: validacao

```kotlin
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class CampoObrigatorio

data class Formulario(
    @CampoObrigatorio val nome: String,
    @CampoObrigatorio val email: String,
    val telefone: String = ""
)
```

Depois, usando reflexao, da pra verificar quais campos tem `@CampoObrigatorio` e validar automaticamente.

### Annotations com use-site targets

Em Kotlin, como propriedades geram campo, getter e setter, as vezes e necessário especificar onde a annotation vai:

```kotlin
class Config(
    @field:NotNull val nome: String,
    @get:JsonProperty("valor_padrao") val valorPadrao: String
)
```

Annotations sao fundamentais no ecossistema Kotlin, especialmente com Spring Boot, Ktor, Room e outros frameworks que dependem de metadados para funcionar.

### Processando annotations com reflexao

Um uso poderoso de annotations e processa-las em tempo de execução para criar comportamentos dinâmicos. Veja como validar campos anotados automaticamente:

```kotlin
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.findAnnotation

@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class Obrigatorio(val mensagem: String = "Campo obrigatorio")

@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class TamanhoMaximo(val valor: Int)

data class CadastroUsuario(
    @Obrigatorio val nome: String,
    @Obrigatorio val email: String,
    @TamanhoMaximo(11) val cpf: String,
    val apelido: String = ""
)

fun <T : Any> validar(obj: T): List<String> {
    val erros = mutableListOf<String>()

    for (prop in obj::class.declaredMemberProperties) {
        val valor = prop.getter.call(obj)?.toString() ?: ""

        prop.findAnnotation<Obrigatorio>()?.let {
            if (valor.isBlank()) erros.add(it.mensagem)
        }

        prop.findAnnotation<TamanhoMaximo>()?.let {
            if (valor.length > it.valor) {
                erros.add("${prop.name} excede ${it.valor} caracteres")
            }
        }
    }
    return erros
}
```

### Annotations para serialização e APIs

Annotations sao amplamente usadas com bibliotecas de serialização como kotlinx.serialization:

```kotlin
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.json.Json

@Serializable
data class ProdutoApi(
    @SerialName("product_id") val id: Int,
    @SerialName("product_name") val nome: String,
    @SerialName("unit_price") val precoUnitario: Double
)

fun main() {
    val json = """{"product_id": 1, "product_name": "Teclado", "unit_price": 299.90}"""
    val produto = Json.decodeFromString<ProdutoApi>(json)
    println(produto.nome) // Teclado
}
```

### Casos de Uso no Mundo Real

- **Injecao de dependência**: frameworks como Koin e Hilt usam annotations como `@Inject`, `@Module` e `@Singleton` para configurar o grafo de dependências automaticamente.
- **Mapeamento de banco de dados**: Room usa `@Entity`, `@PrimaryKey` e `@ColumnInfo` para mapear [data classes](/glossario/data-class/) a tabelas do banco.
- **Endpoints de API**: no Spring Boot e Ktor, annotations como `@GetMapping` e `@PostMapping` mapeiam funções a rotas HTTP.
- **Testes**: `@Test`, `@BeforeEach` e `@ParameterizedTest` do JUnit configuram a execução de testes sem código adicional.
- **Processamento em tempo de compilação**: [KSP](/glossario/ksp/) processa annotations para gerar código automaticamente, eliminando boilerplate.

### Boas Praticas

- Prefira annotations com `AnnotationRetention.SOURCE` ou `BINARY` quando não precisar de reflexao em runtime, pois sao mais eficientes.
- Use `@Target` para restringir onde a annotation pode ser aplicada, evitando uso incorreto.
- Documente o comportamento esperado de annotations customizadas para que outros desenvolvedores saibam como usa-las.
- Sempre especifique use-site targets (`@field:`, `@get:`, `@param:`) quando trabalhar com frameworks Java que esperam annotations em locais específicos.
- Considere usar [KSP](/glossario/ksp/) em vez de reflexao para processar annotations, pois o processamento em tempo de compilação e mais performatico.

### Erros Comuns

- **Esquecer o use-site target**: ao usar annotations de frameworks Java em propriedades Kotlin, a annotation pode ir para o getter em vez do campo. Use `@field:` para garantir o destino correto.
- **Usar RUNTIME retention desnecessariamente**: reflexao em runtime tem custo de performance. Se a annotation só e processada em compilação, use `SOURCE` ou `BINARY`.
- **Criar annotations sem `@Target`**: sem `@Target`, a annotation pode ser aplicada em qualquer lugar, o que pode causar confusao. Sempre defina onde ela e válida.
- **Confundir annotation com lógica de negócio**: annotations sao metadados, não devem conter lógica. A lógica deve estar no processador da annotation.

### Perguntas Frequentes

**Annotations afetam a performance do aplicativo?**
Annotations com retention SOURCE ou BINARY não afetam a performance em runtime, pois sao removidas ou não acessiveis. Apenas annotations com retention RUNTIME podem ter impacto, especialmente quando processadas via reflexao.

**Posso colocar annotations em [lambdas](/glossario/lambda/)?**
Nao diretamente em expressoes lambda, mas você pode anotar o parametro de uma [função de ordem superior](/glossario/higher-order-function/) que recebe a lambda, ou anotar a função que contém a lambda.

**Qual a diferenca entre annotations do Kotlin e do Java?**
Annotations do Kotlin sao compatoveis com Java, mas Kotlin adiciona recursos como use-site targets, parametros com valor padrão e suporte nativo a arrays nos parametros da annotation.

**Posso usar annotations com [companion objects](/glossario/companion-object/)?**
Sim. Voce pode anotar membros de companion objects normalmente. Use `@JvmStatic` para que métodos do companion sejam acessiveis como métodos estaticos em código Java.
