Kotlin Array em Java varargs: como não quebrar a compatibilidade e escrever código limpo
\n\nVocê já escreveu em Kotlin, chamou um bom e velho método Java com varargs — e de repente recebeu um erro de compilação? Se sim, você não está sozinho. A pergunta "Convert Kotlin Array to Java varargs" no Stack Overflow acumulou milhares de visualizações. E não é surpresa: na interseção de duas linguagens, surgem nuances nada óbvias.
Neste artigo, vamos analisar como passar corretamente um array Kotlin para um método Java com número variável de argumentos. Você aprenderá o que é o operador spread, por que Array<String> não é igual a String... e como evitar erros típicos. Vamos lá!
O que são varargs em Java e para que servem
\n\nPara começar, vamos relembrar os conceitos básicos. Varargs (argumentos de comprimento variável) é um mecanismo do Java que permite passar um número arbitrário de argumentos do mesmo tipo para um método. Sintaticamente, é indicado por três pontos após o tipo:
\n\npublic void printMessages(String... messages) {\n for (String msg : messages) {\n System.out.println(msg);\n }\n}\n\nVocê pode chamar este método assim:
\n\nprintMessages("Olá");\nprintMessages("Olá", "Mundo");\nprintMessages(); // chamada vazia também funciona\n\nDentro do método, os argumentos são representados como um array String[]. Mas externamente — é apenas um conjunto de valores separados por vírgulas. Prático, não é?
Agora imagine que você tem um Kotlin Array e quer passá-lo para um método Java como esse. O código ingênuo não funcionará:
\n\nval messages = arrayOf("Olá", "Mundo")\nprintMessages(messages) // Erro de compilação!\n\nPor quê? Porque Kotlin é mais rigoroso com tipos. O método Java espera String..., mas você está passando Array<String>. São coisas diferentes. O compilador vê a incompatibilidade e gera um erro.
Solução: operador spread (operador *)
\n\nEm Kotlin, para esses casos, existe o operador spread — um asterisco * antes do array. Ele literalmente "desempacota" o array em elementos individuais, que são então passados como varargs.
val messages = arrayOf("Olá", "Mundo")\nprintMessages(*messages) // Funciona!\n\nTudo que é genial é simples. Mas vamos entender como isso funciona nos bastidores.
\n\nComo o operador spread transforma os tipos
\n\nQuando você escreve *messages, o Kotlin:
- \n
- Pega cada elemento do array \n
- "Extrai" eles do invólucro
Array\n - Passa como argumentos individuais para o método Java \n
Para o método Java, parece que você escreveu printMessages("Olá", "Mundo"). Nada de arrays — apenas strings puras.
Uma nuance importante: o operador spread funciona apenas com Array (e algumas outras coleções através de toTypedArray()). Um List comum não pode ser desempacotado assim.
Erros típicos e como evitá-los
\n\nMesmo sabendo sobre o operador spread, iniciantes frequentemente cometem erros. Aqui estão os mais comuns.
\n\nErro 1: Passar o array sem o asterisco
\n\n// Incorreto:\nval numbers = intArrayOf(1, 2, 3)\nsomeJavaMethod(numbers) // Erro\n\n// Correto:\nsomeJavaMethod(*numbers.toTypedArray())\n\nObserve: para tipos primitivos (IntArray, DoubleArray, etc.) é necessário primeiro converter para Array usando .toTypedArray(). O operador spread funciona apenas com arrays de objetos.
Erro 2: Confusão com List
\n\nMuitos tentam passar um List<String> diretamente:
val list = listOf("A", "B")\nprintMessages(*list) // Erro! List != Array\n\nSolução: primeiro converta a lista para um array:
\n\nprintMessages(*list.toTypedArray())