O Kotlin 2.2 chegou para consolidar tendências que vinham se desenhando desde o trabalho pesado do compilador K2. Se o Kotlin 2.1 marcou a maturidade do K2 como padrão e a estabilização de guard conditions, o 2.2 é a versão em que recursos antes experimentais finalmente viram ferramenta de produção — em especial os context parameters, que substituem os antigos context receivers com uma sintaxe mais limpa e segura.
Neste guia, você vai ver o que realmente muda no seu código, com exemplos práticos. A ideia é fugir do marketing e focar no que afeta o dia a dia de quem mantém apps Android, backends em Spring ou Ktor e bibliotecas multiplataforma. Se você quer uma visão mais ampla do ecossistema, vale revisar também o nosso panorama de novidades do Kotlin em 2026 e o guia completo de KSP, que ganhou performance extra nesta versão.
1. Context Parameters: o recurso central do Kotlin 2.2
O maior destaque do Kotlin 2.2 é a estabilização dos context parameters. Eles resolvem um problema clássico: como passar dependências implícitas (um CoroutineScope, um Logger, um receptor de DSL) sem poluir a assinatura de cada função e sem apelar para threads locais mutáveis.
Antes do 2.2 existiam os context receivers, que eram experimentais e tinham limitações confusas de resolução de ambiguidade. O novo mecanismo é mais explícito:
context(scope: CoroutineScope, logger: Logger)
fun saveUser(user: User) {
launch {
logger.info("Salvando ${user.id}")
repository.put(user)
}
}
Aqui scope e logger são declarados como parâmetros de contexto. Para chamar saveUser, você precisa de um CoroutineScope e de um Logger no escopo da chamada, o que o compilador verifica estaticamente. A diferença para os context receivers antigos é que agora há nomes explícitos e regras claras de precedência, o que elimina a maior parte dos erros difíceis de debugar.
Como prover um contexto
O contexto é fornecido por uma extensão marcada com context no próprio receptor, ou por um bloco with:
with(MyAppScope, consoleLogger) {
saveUser(currentUser) // resolve scope e logger automaticamente
}
O ganho prático aparece em código de biblioteca e em DSLs. Em vez de repetir o mesmo Receiver em dezenas de funções internas, você declara uma vez e o compilador propaga. Para aprofundar o padrão de DSL, veja o nosso tutorial de extension functions e o guia de Kotlin DSL do Gradle, onde context parameters deixam o código idiomático consideravelmente mais limpo.
Migração dos context receivers antigos
Se você usava context receivers experimentais, a migração é direta mas não é só renomear. As principais mudanças:
- A cláusula
context(...)agora exige nomes (context(logger: Logger)), não apenas tipos. - Quando há ambiguidade de contexto, o compilador aponta explicitamente qual nome resolver — antes era um erro vago.
- O modificador
-Xcontext-receiversfoi substituído por-Xcontext-parameters, e o antigo emite warning de depreciação.
Rode o build com a flag nova, corrija os nomes ausentes e remova o flag antigo do build.gradle.kts. A maioria dos projetos migra em poucas horas.
2. Smart cast mais inteligente e abrangente
O Kotlin sempre teve smart cast, mas havia buracos irritantes: propriedades val mutáveis de outras classes, resultados de && curto-circuitado e desestruturação de data classes nem sempre eram reconhecidos. O 2.2 estreia um smart-cast reformulado por cima do K2 que cobre vários desses casos.
Antes, este código precisava de cast explícito ou de uma variável local temporária:
class Container {
val value: Any? = compute()
}
fun handle(c: Container) {
if (c.value is String) {
// antes: precisava de (c.value as String)
println(c.value.length)
}
}
No Kotlin 2.2, desde que o val seja efetivamente imutável durante a análise, o smart cast é aplicado diretamente. O mesmo vale para combinar null checks encadeados:
fun process(user: User?, settings: Settings?) {
if (user != null && settings != null && settings.strict) {
// user e settings são non-null aqui, mesmo sendo parâmetros nullable
user.notify(settings)
}
}
Isso reduz ruído visual e diminui o número de warnings de CastCanBeNull. Para quem mantém código legado cheio de let, vale revisar nosso guia de null safety para identificar onde os casts explícitos viraram desnecessários.
3. Melhorias no compilador K2 e tempos de build
O K2 já era o padrão, mas o 2.2 traz otimizações específicas de backend que afetam projetos grandes. Os destaques mensurados:
- Redução de 10% a 15% no tempo de compilação incremental em monorepos, especialmente quando há muitos módulos KMP.
- Melhor cache de inferência de tipos, evitando recomputar árvores inteiras após pequenas edições.
- Diagnósticos mais precisos: mensagens de erro agora apontam o local exato na expressão em vez de só marcar a função inteira.
Se você usa Gradle Version Catalogs e build cache distribuído, o ganho compõe: o K2 mais rápido reduz o custo de cache misses. Para times que medem CI, a dica é comparar o compileKotlin antes e depois da migração usando o relatório do Gradle.
4. Multi-dollar string interpolation refinada
O 2.1 introduziu a interpolação com múltiplos cifrões ($$). O 2.2 refinou as regras de escape para evitar armadilhas comuns — em especial quando o conteúdo interpolado contém chaves ou expressões com $:
val amount = 1_000
val currency = "BRL"
// interpolacao multi-dollar permite expressoes complexas sem escape
val msg = $$"Total: ${formatCurrency(amount, currency)} (taxa incluída)"
As regras agora são: dentro de $$"...", o ${...} é sempre tratado como interpolação Kotlin, e um $ sozinho é literal. Antes, misturar ${} com texto que continha cifrões (como valores monetários) quebrava o build. Isso é especialmente útil em templates de relatório, SQL gerado e mensagens de log estruturadas.
5. AutoCloseable e cleanup determinístico
O Kotlin 2.2 padroniza o uso de AutoCloseable com uma extensão use aprimorada e suporte a try-with-resources mais idiomático. A novidade é que agora qualquer classe que implemente AutoCloseable pode ser combinada com ScopedValue-like patterns via context parameters:
context(db: Database)
fun findAll(): List<User> = db.query("SELECT * FROM users")
fun main() = Database.connect(url).use { db ->
with(db) {
findAll().forEach { println(it) }
}
}
O use garante o fechamento mesmo em exceções, e o contexto elimina a necessidade de passar db explicitamente para cada função do domínio. É um padrão forte para backends em Ktor e Spring Boot, onde o gerenciamento de conexões era sempre um boilerplate chato.
6. Kotlin/Wasm e Kotlin/JS
Continua a estabilização de Kotlin/Wasm. O 2.2 marca o target Wasm como estável para apps Compose Multiplatform Web, com garbage collector padrão e suporte completo a source maps. Para Kotlin/JS, o foco foi reduzir o tamanho de bundle com tree-shaking mais agressivo.
Para quem compara caminhos de frontend multiplataforma, é útil cruzar com o Kotlin vs TypeScript: enquanto TypeScript segue dominando a web, Kotlin/Wasm abre espaço para compartilhar lógica de domínio entre Android, iOS e Web sem reescrever em JS.
Como migrar para o Kotlin 2.2
A migração é direta para a maioria dos projetos. Passos recomendados:
- Atualize o plugin Kotlin no
build.gradle.ktspara2.2.xe o Gradle para a versão mínima suportada. - Ative context parameters adicionando
-Xcontext-parametersemkotlinOptions.freeCompilerArgs(e remova-Xcontext-receivers). - Rode o inspetor de ABI com
:checkpara detectar mudanças incompatíveis em bibliotecas internas. - Revise smart casts removidos: o que antes exigia
aspode ser limpo, mas falso positivos podem mascarar bugs — rode os testes. - Atualize dependências que dependem do compilador (KSP, Room, Hilt, Moshi) para versões compatíveis com Kotlin 2.2.
Para apps Android, atualize o Android Studio para a versão que suporta o plugin Kotlin 2.2 e sincronize o projeto. Times que usam Hilt devem aguardar a release compatível do Hilt-KSP, que costuma sair poucas semanas depois da linguagem.
Vale a pena migrar agora?
Para bibliotecas e novos projetos, sim — context parameters e o smart cast melhorado valem a pena desde o primeiro commit. Para apps em produção estáveis, a migração pode esperar o ponto de release dos principais processadores de anotação, mas planeje para o próximo trimestre. O risco de ficar em 2.1 por muito tempo é acumular débito de features e perder ganhos de produtividade que já estão maduros.
Se você compara Kotlin com outras linguagens do ecossistema backend, vale olhar o Kotlin vs Go e o Kotlin vs Rust. Quem busca desempenho bruto em concorrência pode complementar com Go para serviços de alto throughput, ou Rust para componentes de baixo nível — e em pipelines de dados, Python segue sendo a escolha para ML e ciência de dados.
Conclusão
O Kotlin 2.2 não é uma revolução: é uma versão de consolidação. Context parameters estáveis finalmente resolvem um problema de ergonomia que a comunidade pediu por anos, o smart cast reformulado remove código redundante, e o K2 continua ficando mais rápido. Para quem já estava em 2.1, a migração é de baixo risco e alto retorno em legibilidade.
A recomendação prática é: migre bibliotecas e projetos novos imediatamente, agende a migração de apps estáveis para o próximo ciclo de release, e comece a refatorar context receivers experimentais assim que possível, antes que a depreciação vire erro. O ecossistema — Spring, Ktor, Compose, KMP — já está preparado, então não há razão para segurar.