Kotlin Array en Java varargs: cómo no romper la compatibilidad y escribir código limpio
\n\n¿Alguna vez has escrito en Kotlin, llamado a un viejo método Java con varargs y de repente has recibido un error de compilación? Si es así, no estás solo. La pregunta "Convert Kotlin Array to Java varargs" en Stack Overflow ha acumulado miles de visitas. Y no es de extrañar: en la intersección de dos lenguajes a menudo surgen matices no evidentes.
En este artículo, analizaremos cómo pasar correctamente un array de Kotlin a un método Java con un número variable de argumentos. Aprenderás qué es el operador spread, por qué Array<String> no es igual a String... y cómo evitar errores típicos. ¡Allá vamos!
¿Qué son los varargs en Java y para qué sirven?
\n\nPara empezar, recordemos los conceptos básicos. Varargs (argumentos de longitud variable) es un mecanismo de Java que permite pasar a un método una cantidad arbitraria de argumentos del mismo tipo. Sintácticamente, se denota con tres puntos después del tipo:
\n\npublic void printMessages(String... messages) {\n for (String msg : messages) {\n System.out.println(msg);\n }\n}\n\nPuedes llamar a este método así:
\n\nprintMessages("Hello");\nprintMessages("Hello", "World");\nprintMessages(); // la llamada vacía también funciona\n\nDentro del método, los argumentos se representan como un array String[]. Pero desde fuera, es solo un conjunto de valores separados por comas. Práctico, ¿verdad?
Ahora imagina que tienes un Kotlin Array y quieres pasarlo a dicho método Java. El código ingenuo no funcionará:
\n\nval messages = arrayOf("Hello", "World")\nprintMessages(messages) // ¡Error de compilación!\n\n¿Por qué? Porque Kotlin es más estricto con los tipos. El método Java espera String..., pero tú estás pasando Array<String>. Son cosas diferentes. El compilador ve la discrepancia y lanza un error.
Solución: operador spread (operador *)
\n\nEn Kotlin, para estos casos existe el operador spread: un asterisco * delante del array. Literalmente "despliega" el array en elementos individuales, que luego se pasan como varargs.
val messages = arrayOf("Hello", "World")\nprintMessages(*messages) // ¡Funciona!\n\nTodo lo genial es simple. Pero analicemos cómo funciona bajo el capó.
\n\nCómo el operador spread transforma los tipos
\n\nCuando escribes *messages, Kotlin:
- \n
- Toma cada elemento del array \n
- Los "saca" del envoltorio
Array\n - Los pasa como argumentos individuales al método Java \n
Para el método Java, se ve como si hubieras escrito printMessages("Hello", "World"). Sin arrays, solo cadenas puras.
Un matiz importante: el operador spread solo funciona con Array (y algunas otras colecciones a través de toTypedArray()). Un List normal no se puede desplegar así.
Errores típicos y cómo evitarlos
\n\nIncluso conociendo el operador spread, los principiantes suelen cometer errores. Estos son los más comunes.
\n\nError 1: Pasar el array sin el asterisco
\n\n// Incorrecto:\nval numbers = intArrayOf(1, 2, 3)\nsomeJavaMethod(numbers) // Error\n\n// Correcto:\nsomeJavaMethod(*numbers.toTypedArray())\n\nTen en cuenta: para tipos primitivos (IntArray, DoubleArray, etc.) primero debes convertirlos a Array mediante .toTypedArray(). El operador spread solo funciona con arrays de objetos.
Error 2: Confusión con List
\n\nMuchos intentan pasar un List<String> directamente:
val list = listOf("A", "B")\nprintMessages(*list) // ¡Error! List != Array\n\nSolución: primero convierte la lista en un array:
\n\nprintMessages(*list.toTypedArray())