---
title: "val em Kotlin: O que É e Como Funciona | Kotlin Brasil"
url: "https://kotlin.dev.br/glossario/val/"
markdown_url: "https://kotlin.dev.br/glossario/val.MD"
description: "Entenda o que é val em Kotlin, como declarar variáveis imutáveis e por que usar val é uma boa prática no desenvolvimento Kotlin."
date: "2026-02-01"
author: "Karina Melo"
---

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

Entenda o que é val em Kotlin, como declarar variáveis imutáveis e por que usar val é uma boa prática no desenvolvimento Kotlin.


## O que é `val` em Kotlin?

A palavra-chave `val` em Kotlin serve para declarar **variáveis somente leitura**, ou seja, uma vez que você atribui um valor a ela, não dá pra mudar depois. É como se fosse uma constante local — você define o valor e pronto, ele fica fixo dali em diante.

Se você já programou em Java, pode pensar no `val` como o equivalente ao `final`. A diferença é que em Kotlin, usar `val` é muito mais natural e incentivado pela própria linguagem.

### Por que usar `val`?

A grande sacada de usar `val` é tornar o código mais **previsível e seguro**. Quando você garante que um valor não vai mudar, fica muito mais fácil de entender o que tá acontecendo no programa. Menos bugs, menos dor de cabeça.

Na prática, a recomendação da comunidade Kotlin é: **sempre comece com `val`**. Só troque pra `var` se realmente precisar alterar o valor depois.

### Exemplo prático

```kotlin
fun main() {
    val nome = "Kotlin Brasil"
    val ano = 2026

    println("Bem-vindo ao $nome! Estamos em $ano.")

    // Isso aqui daria erro de compilacao:
    // nome = "Outro nome"  // Val cannot be reassigned
}
```

Perceba que o compilador já infere o tipo automaticamente. O `nome` é uma `String` e o `ano` é um `Int`, sem precisar declarar isso explicitamente.

### `val` não significa imutável em tudo

Um ponto importante: `val` garante que a **referência** não muda, mas o conteúdo do objeto pode mudar. Por exemplo, se você declara uma lista mutável com `val`, não pode reatribuir a variável, mas pode adicionar itens na lista.

```kotlin
val frutas = mutableListOf("Manga", "Acerola")
frutas.add("Goiaba") // Funciona!
// frutas = mutableListOf("Banana") // Erro! Não pode reatribuir
```

Essa distinção é fundamental pra quem tá começando com Kotlin. Usar `val` sempre que possível é uma prática que vai deixar seu código mais limpo e confiável.

### `val` com tipos explícitos e inicialização tardia

Em algumas situações, você pode querer declarar o tipo explicitamente ou inicializar o `val` em momentos diferentes dentro do mesmo bloco.

```kotlin
fun calcularDesconto(preco: Double, porcentagem: Int): String {
    val desconto: Double
    val mensagem: String

    if (porcentagem > 0) {
        desconto = preco * porcentagem / 100
        mensagem = "Desconto de R$ ${"%.2f".format(desconto)}"
    } else {
        desconto = 0.0
        mensagem = "Sem desconto aplicado"
    }

    return mensagem
}

fun main() {
    println(calcularDesconto(150.0, 10)) // Desconto de R$ 15,00
    println(calcularDesconto(80.0, 0))   // Sem desconto aplicado
}
```

O compilador do Kotlin permite que um `val` seja atribuído em branches diferentes de um `if` ou `when`, desde que ele seja atribuído exatamente uma vez em todos os caminhos possíveis.

### `val` em data classes e propriedades

O `val` é amplamente usado em `data class` para criar objetos imutáveis, um padrão muito valorizado em programação funcional e em aplicações concorrentes.

```kotlin
data class Produto(
    val nome: String,
    val preco: Double,
    val categoria: String
)

fun main() {
    val notebook = Produto("Notebook", 3500.0, "Eletrônicos")
    println(notebook) // Produto(nome=Notebook, preco=3500.0, categoria=Eletrônicos)

    // Para "alterar", crie uma cópia com copy()
    val comDesconto = notebook.copy(preco = 2990.0)
    println(comDesconto) // Produto(nome=Notebook, preco=2990.0, categoria=Eletrônicos)
}
```

### Casos de Uso no Mundo Real

- **Configurações de aplicação**: Valores como URL base da API, chaves de configuração e timeouts são naturalmente imutáveis. Declará-los com `val` garante que nenhuma parte do código vai alterar esses valores acidentalmente durante a execução.
- **Resultados de consultas ao banco**: Quando você busca dados do banco ou de uma API, o resultado retornado não deve ser modificado. Usar `val` para armazenar esses resultados evita alterações involuntárias que poderiam causar inconsistências.
- **Injeção de dependências**: Em frameworks como Koin e Dagger/Hilt, as dependências injetadas são declaradas com `val`. Uma vez injetado, o serviço ou repositório não deve ser substituído durante o ciclo de vida do componente.
- **Parâmetros de funções em Kotlin**: Todos os parâmetros de funções em Kotlin são implicitamente `val`. Você não pode reatribuí-los dentro do corpo da função, o que é uma decisão de design da linguagem que evita efeitos colaterais inesperados.

### Boas Práticas

- **Comece sempre com `val`**: Essa é a regra número um. Declare tudo como `val` primeiro. Só mude para `var` se o compilador indicar que você precisa reatribuir o valor. Essa abordagem é chamada de "immutability by default".
- **Combine `val` com coleções imutáveis**: Use `listOf()`, `mapOf()` e `setOf()` junto com `val` para garantir imutabilidade total. Usar `val` com `mutableListOf()` protege apenas a referência, não o conteúdo.
- **Use `val` em propriedades de classe**: Propriedades declaradas com `val` em classes são thread-safe para leitura, pois não podem ser reatribuídas após a construção do objeto.
- **Prefira `val` com expressões `when` e `if`**: Em Kotlin, `if` e `when` são expressões que retornam valor. Use `val resultado = when { ... }` em vez de declarar um `var` e atribuir dentro de cada branch.
- **Considere `const val` para constantes de compilação**: Quando o valor é uma primitiva ou String conhecida em tempo de compilação, use `const val` no companion object para otimizar a performance.

### Erros Comuns

- **Achar que `val` torna o objeto completamente imutável**: Como mostrado acima, `val` protege apenas a referência. Se o objeto apontado é mutável (como `MutableList`), seu conteúdo interno ainda pode ser alterado. Para imutabilidade total, combine `val` com tipos imutáveis.
- **Usar `var` por hábito de outras linguagens**: Quem vem de Java, JavaScript ou Python tende a usar `var` para tudo. Em Kotlin, isso desperdiça uma das maiores vantagens da linguagem. O IntelliJ IDEA inclusive mostra um aviso quando um `var` nunca é reatribuído.
- **Confundir `val` com `const val`**: `val` é avaliado em tempo de execução, enquanto `const val` é avaliado em tempo de compilação. `const val` só pode ser usado com tipos primitivos e String em objetos ou companion objects.
- **Não usar `val` em loops for**: A variável de iteração em um `for` já é implicitamente `val`. Tentar reatribuí-la dentro do loop causa erro de compilação, o que é o comportamento correto e esperado.
- **Declarar `val` sem inicializar fora de condicionais**: Um `val` deve ser inicializado antes de ser usado. Se você declará-lo sem valor e esquecer de atribuir em algum branch do código, o compilador vai apontar o erro.

### Perguntas Frequentes

**Qual a diferença entre `val` e `const val`?** `val` pode receber qualquer valor em tempo de execução, incluindo resultados de funções e objetos complexos. `const val` é restrito a tipos primitivos e String, precisa ser declarado em companion objects ou top-level, e o valor é embutido diretamente no bytecode em tempo de compilação.

**`val` é a mesma coisa que `final` em Java?** Conceitualmente sim, ambos impedem a reatribuição da variável. A diferença é que em Kotlin, `val` é a forma padrão e incentivada de declarar variáveis, enquanto `final` em Java é uma anotação adicional que poucos desenvolvedores usam consistentemente.

**Posso usar `val` com `lateinit`?** Não. `lateinit` só pode ser usado com `var`, pois a variável precisa ser atribuída depois da declaração, o que contradiz a natureza somente-leitura do `val`. Para inicialização tardia com `val`, use `by lazy`.

**`val` torna meu código mais lento?** Não. Na verdade, o compilador pode fazer otimizações mais agressivas quando sabe que um valor não vai mudar. Além disso, `val` não gera overhead de runtime — no bytecode, a diferença é simplesmente a ausência de um método setter.

### Termos Relacionados

- [var](/glossario/var) — A contraparte mutável de `val`, usada quando o valor precisa ser reatribuído.
- [Data Class](/glossario/data-class) — Classes de dados que usam `val` para criar objetos imutáveis.
- [Null Safety](/glossario/null-safety) — Sistema de tipos nulos do Kotlin, frequentemente combinado com `val` para variáveis seguras.
- [when](/glossario/when) — Expressão que retorna valor e combina perfeitamente com `val` para atribuição condicional.
