Uma das features mais pedidas pela comunidade Kotlin finalmente está tomando forma. No Kotlin 2.4.0-Beta2, lançado em 22 de abril de 2026, a JetBrains introduziu os collection literals — uma nova sintaxe experimental que permite criar coleções usando colchetes [], similar ao que você já conhece em Python, JavaScript ou Swift.

Se você acompanhou as novidades do Kotlin 2.4.0 Beta, sabe que essa release veio carregada. Mas os collection literals são, na opinião de muitos devs, a mudança mais impactante no dia a dia de quem escreve Kotlin.

O problema que os collection literals resolvem

Hoje, para criar uma lista simples em Kotlin, você usa listOf():

val frutas = listOf("maçã", "banana", "laranja")
val numeros = mutableListOf(1, 2, 3, 4, 5)
val mapa = mapOf("chave" to "valor", "nome" to "Kotlin")

Funciona bem, mas é verboso comparado a outras linguagens. Em Python, seria ["maçã", "banana", "laranja"]. Em JavaScript, a mesma coisa. O Kotlin sempre priorizou concisão — veja as data classes, scope functions e lambdas — e os collection literals seguem essa filosofia.

A nova sintaxe com colchetes

Com collection literals habilitados, a mesma lista fica assim:

val frutas = ["maçã", "banana", "laranja"]
val numeros = [1, 2, 3, 4, 5]

Simples, limpo e direto. O compilador infere o tipo automaticamente — no caso acima, List<String> e List<Int>, respectivamente.

Tipo padrão é List (imutável)

Quando você cria um literal sem declarar o tipo, o Kotlin infere como List imutável:

val cores = ["vermelho", "azul", "verde"]
// Tipo inferido: List<String>

Para criar uma lista mutável, declare o tipo explicitamente:

val coresMutaveis: MutableList<String> = ["vermelho", "azul", "verde"]
coresMutaveis.add("amarelo") // Funciona!

Isso é consistente com a filosofia do Kotlin de preferir imutabilidade por padrão — se você quer algo mutável, precisa ser explícito.

Usando com tipos específicos

Você pode declarar o tipo desejado e o compilador se adapta:

val listaImutavel: List<Int> = [1, 2, 3]
val listaMutavel: MutableList<Int> = [1, 2, 3]
val conjunto: Set<String> = ["kotlin", "java", "scala"]
val conjuntoMutavel: MutableSet<String> = ["kotlin", "java"]

Note que a sintaxe [] funciona para List, MutableList, Set e MutableSet. Para mapas, a sintaxe é um pouco diferente — veremos adiante.

Collection literals em parâmetros de função

Onde os collection literals realmente brilham é em chamadas de função. Compare o antes e depois:

Antes (Kotlin atual)

fun processarPedido(itens: List<String>, prioridades: Set<Int>) {
    // lógica
}

processarPedido(
    itens = listOf("Notebook", "Mouse", "Teclado"),
    prioridades = setOf(1, 2, 3)
)

Depois (com collection literals)

processarPedido(
    itens = ["Notebook", "Mouse", "Teclado"],
    prioridades = [1, 2, 3]    // inferido como Set<Int> pelo tipo do parâmetro
)

O compilador usa o tipo do parâmetro da função para decidir se deve criar uma List ou um Set. Isso elimina a necessidade de chamar listOf() ou setOf() em toda chamada de função.

Esse pattern fica especialmente útil em DSLs e configurações com Kotlin DSL no Gradle, onde listas de dependências e configurações são comuns.

Collection literals e annotations

Uma área onde collection literals fazem diferença imediata é em annotations:

@Suppress(["UNCHECKED_CAST", "DEPRECATION"])
fun minhaFuncao() {
    // ...
}

@Target([AnnotationTarget.CLASS, AnnotationTarget.FUNCTION])
annotation class MinhaAnnotation

Até agora, o Kotlin usava arrayOf() em annotations — os collection literals oferecem uma alternativa mais limpa.

Combinando com outras features do Kotlin

Com when expressions

Os collection literals combinam naturalmente com o when do Kotlin:

fun classificarFruta(fruta: String): String = when (fruta) {
    in ["maçã", "pera", "uva"] -> "Fruta temperada"
    in ["manga", "abacaxi", "mamão"] -> "Fruta tropical"
    in ["morango", "framboesa", "mirtilo"] -> "Fruta vermelha"
    else -> "Fruta desconhecida"
}

Com destructuring

Combinado com destructuring, fica ainda mais expressivo:

val (primeiro, segundo, terceiro) = ["Kotlin", "Java", "Scala"]
println("Preferida: $primeiro") // Preferida: Kotlin

Com higher-order functions

A integração com higher-order functions e o ecossistema de collections é natural:

val resultado = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    .filter { it % 2 == 0 }
    .map { it * it }
    .sum()

println(resultado) // 220

Como habilitar collection literals

Como essa feature é experimental no Kotlin 2.4.0-Beta2, você precisa habilitar explicitamente. Adicione no build.gradle.kts:

kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xsupport-collection-literals")
    }
}

Ou, se preferir habilitar por arquivo, use a annotation:

@file:OptIn(ExperimentalCollectionLiterals::class)

Lembre-se: como é experimental, a API pode mudar até atingir o status estável. Para projetos em produção, avalie o risco. Para projetos pessoais e protótipos, vale experimentar desde já.

Se você usa Gradle Version Catalogs no projeto, atualize a versão do Kotlin no libs.versions.toml:

[versions]
kotlin = "2.4.0-Beta2"

Impacto na legibilidade do código

Vamos comparar um cenário mais realista — configuração de um cliente HTTP com Ktor:

Antes

val config = HttpClientConfig(
    headers = mapOf(
        "Content-Type" to "application/json",
        "Accept" to "application/json"
    ),
    retryStatusCodes = listOf(503, 429, 502),
    allowedMethods = setOf("GET", "POST", "PUT", "DELETE")
)

Depois

val config = HttpClientConfig(
    headers = mapOf(
        "Content-Type" to "application/json",
        "Accept" to "application/json"
    ),
    retryStatusCodes = [503, 429, 502],
    allowedMethods = ["GET", "POST", "PUT", "DELETE"]
)

A diferença parece sutil em exemplos pequenos, mas em bases de código grandes — especialmente em testes unitários com muitos dados de entrada — a economia de digitação e a clareza visual são significativas.

O que ainda falta

Apesar do avanço, alguns pontos ainda estão em discussão pela equipe do Kotlin:

  • Map literals: ainda não há sintaxe literal para mapas. Você continua usando mapOf("chave" to "valor"). A comunidade está debatendo opções como ["chave": "valor"] ou {"chave": "valor"}
  • Array literals: a sintaxe atual não cobre arrays primitivos (IntArray, ByteArray, etc.)
  • Inferência em contextos complexos: em alguns cenários com generics avançados, a inferência pode exigir type annotations explícitas

Collection literals vs. outras linguagens

LinguagemListaMapa
Kotlin (novo)[1, 2, 3]mapOf(1 to "a")
Python[1, 2, 3]{1: "a"}
Swift[1, 2, 3][1: "a"]
JavaScript[1, 2, 3]{1: "a"}
JavaList.of(1, 2, 3)Map.of(1, "a")

O Kotlin está se alinhando com a sintaxe que desenvolvedores de outras linguagens já conhecem, reduzindo a curva de aprendizado. Se você veio do Python ou JavaScript e está aprendendo Kotlin, essa sintaxe vai parecer familiar.

Quando usar e quando evitar

Use collection literals quando:

  • Criar listas/sets inline em chamadas de função
  • Escrever testes com dados de exemplo
  • Configurar DSLs e builders
  • Inicializar constantes simples

Evite por enquanto quando:

  • O projeto precisa de estabilidade máxima (ainda é experimental)
  • Você precisa de arrays primitivos para performance
  • O time ainda não está no Kotlin 2.4+

Conclusão

Os collection literals são uma adição natural e bem-vinda ao Kotlin. A sintaxe com colchetes é mais concisa, mais familiar para quem vem de outras linguagens, e se integra perfeitamente com o sistema de tipos do Kotlin. Se você já programa em Python, vai notar que a sintaxe [1, 2, 3] é praticamente idêntica — e essa familiaridade é intencional.

Mesmo sendo experimental, vale a pena começar a experimentar em projetos pessoais e acompanhar a evolução para a versão estável. Com o Kotlin 2.4.0 trazendo também context parameters estáveis, explicit backing fields e melhorias no Kotlin/Wasm, o ecossistema continua evoluindo em ritmo forte.

Se você está começando com Kotlin, confira nosso guia completo e o tutorial de variáveis e tipos para entender a base antes de mergulhar em features avançadas. E para ficar por dentro de todas as novidades, acompanhe nosso blog e a seção de tendências Kotlin 2026.


Perguntas Frequentes

Os collection literals já podem ser usados em produção?

Não, os collection literals ainda são experimentais no Kotlin 2.4.0-Beta2. A API pode mudar antes de atingir o status estável. Use em projetos pessoais e protótipos por enquanto, e aguarde a estabilização antes de adotar em produção.

Qual a diferença entre [1, 2, 3] e listOf(1, 2, 3)?

Funcionalmente, nenhuma. O compilador traduz [1, 2, 3] para o mesmo bytecode que listOf(1, 2, 3). A diferença é puramente sintática — os collection literals oferecem uma escrita mais concisa e familiar.

Posso criar mapas com collection literals?

Ainda não. Na versão atual, os collection literals suportam List, MutableList, Set e MutableSet. A sintaxe para mapas ainda está sendo discutida pela equipe do Kotlin. Por enquanto, continue usando mapOf().

Preciso atualizar o Kotlin para usar collection literals?

Sim, você precisa do Kotlin 2.4.0-Beta2 ou superior e habilitar a flag experimental -Xsupport-collection-literals no compilador. Também funciona com a annotation @file:OptIn(ExperimentalCollectionLiterals::class) por arquivo.