Kotlin
A concise multiplatform language developed by JetBrains
Escalar la adopción de Kotlin en su organización
Artículo de Urs Peter, ingeniero de software sénior y formador de Kotlin certificado por JetBrains. Para los lectores que busquen una forma más estructurada de desarrollar sus habilidades en Kotlin, Urs también dirige el Kotlin Upskill Program en Xebia Academy.
Este es el quinto artículo de La guía definitiva para adoptar Kotlin en un entorno dominado por Java, una serie que sigue cómo crece la adopción de Kotlin entre equipos reales, desde la curiosidad de un único desarrollador hasta la transformación de toda la empresa.
Todos los artículos de la serie:
- Introducción a Kotlin para desarrolladores Java
- Evaluación de Kotlin en proyectos reales
- Aumentar la adopción de Kotlin en su empresa
- Ayudar a los responsables a decir sí a Kotlin
- Escalar la adopción de Kotlin en su organización
Factores de éxito para la adopción de Kotlin a gran escala
Lograr la aceptación de Kotlin por parte de los desarrolladores y el apoyo de la dirección es un hito importante, pero no es la línea de meta. El verdadero reto comienza cuando se enfrenta a bases de código Java existentes que deben coexistir con Kotlin o hacer la transición a este. ¿Cómo navegar eficazmente por este mundo híbrido?
La clave para gestionar las bases de código antiguas es desarrollar una estrategia que se alinee con sus objetivos organizativos y sus realidades operativas. Este es un enfoque demostrado que ha funcionado bien en la práctica.
Estrategia del ciclo de vida de las aplicaciones
Las distintas aplicaciones requieren enfoques diferentes en función de la fase de su ciclo de vida. Examinemos tres categorías distintas:
Aplicaciones al final de su vida útil
Estrategia: déjelas tranquilas.
Si se ha programado que una aplicación se retire, no hay motivos empresariales para la migración. Mantenga estos sistemas en Java y concentre su energía donde más importa. El coste de la migración nunca estará justificado por la vida útil restante de la aplicación.
Nuevos sistemas
Estrategia: por defecto a Kotlin.
En las organizaciones en las que ya se ha adoptado Kotlin por completo, los proyectos nuevos comienzan de forma natural con Kotlin. Si el proceso de adopción está en marcha, los equipos suelen tener que elegir entre Java y Kotlin. Elija sabiamente ;-).
Aplicaciones activas
Estrategia: migración pragmática y basada en funcionalidades.
Las aplicaciones activas son las que requieren una consideración atenta: reescribir por reescribir no será un argumento que convenza al propietario del producto. En su lugar, combine los esfuerzos de migración con el desarrollo de nuevas funcionalidades. Este enfoque ofrece un valor empresarial tangible a la vez que moderniza su base de código. Los diferentes ángulos de ataque ya los hemos tratado en el apartado: Ampliar o convertir una aplicación Java existente.
Enfoques de conversión de Java a Kotlin
Al convertir Java a Kotlin, tiene varias opciones, y cada una presenta sus propios compromisos:
1. Reescritura completa
Ideal para: pequeñas bases de código
Reto: requiere mucho tiempo para los sistemas más grandes
Reescribir una base de código desde cero le ofrece el código Kotlin más limpio e idiomático. Este enfoque es adecuado para bases de código pequeñas, como un microservicio. Para bases de código grandes, este enfoque suele ser prohibitivamente caro.
2. Autoconversión del IDE con perfeccionamiento manual
Ideal para: bases de código medianas con tiempo dedicado a la refactorización
Reto: las reparaciones manuales son obligatorias
La función Convert Java to Kotlin de IntelliJ IDEA proporciona una traducción literal que dista mucho de ser idiomática. Veamos este ejemplo:
Intento 1:
Java
record Developer(
String name,
List languages
) {}
Resultado bruto de la autoconversión:
Kotlin
@JvmRecord data class Developer( val name: String?, val languages: MutableList? )
Esta conversión tiene varios problemas:
- Todo se vuelve anulable (demasiado defensivo).
- Las colecciones de Java se convierten en
MutableListde Kotlin en lugar de en la lista de solo lectura predeterminada de Kotlin.
Mejora de la conversión con anotaciones jspecify:
Por suerte, para la conversión de todos los tipos Java a tipos Nullable en Kotlin, existe una solución en forma de anotaciones @NonNull/@Nullable. Existen diferentes opciones; la más moderna es jspecify, que recientemente también ha sido admitida oficialmente por Spring:
org.jspecify
jspecify
1.0.0
implementation("org.jspecify:jspecify:1.0.0")
Con jspecify, podemos anotar el código Java con @Nullable y @NonNull.
Intento 2:
Java
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
record Developer(
@NonNull String name,
@NonNull List languages,
@Nullable String email
) {}
Ahora la autoconversión da mucho mejores resultados:
Kotlin
@JvmRecord data class Developer( //😃 non-null as requested val name: String, //😃 both, collection and type are non-null val languages: MutableList, //😃 nullable as requested val email: String?, )
Limitaciones del enfoque de autoconversión:
Incluso con anotaciones jspecify, los patrones Java complejos no se traducen bien. Vea este ejemplo de código autoconvertido mostrado en el apartado: 3. No más excepciones comprobadas, pero el código en Kotlin es más seguro:
Kotlin
fun downloadAndGetLargestFile(urls: MutableList): String? {
//🤨 using Stream, instead of Kotlin Collections
val contents = urls.stream().map { urlStr: String? ->
//🤨 still using Optional, rather than Nullable types
//🤨 var but we want val!
var optional: Optional
//🤨 useless try-catch, no need to catch in Kotlin
try {
optional = Optional.of(URI(urlStr).toURL())
} catch (e: URISyntaxException) {
optional = Optional.empty()
} catch (e: MalformedURLException) {
optional = Optional.empty()
}
optional
}.filter { it!!.isPresent() }//🤨 discouraged !! to force conversion to non-null
.map {it.get() }
.map { url: URL ->
//🤨 useless try-catch, no need to catch in Kotlin
try {
url.openStream().use { `is` ->
String(`is`.readAllBytes(), StandardCharsets.UTF_8)
}
} catch (e: IOException) {
throw IllegalArgumentException(e)
}
}.toList()
//🤨 usage of Java collections…
return Collections.max(contents)
}
La autoconversión está muy lejos del resultado deseado e idiomático:
Kotlin
fun downloadAndGetLargestFile(urls: List): String? =
urls.mapNotNull {
runCatching { URI(it).toURL() }.getOrNull()
}.maxOfOrNull{ it.openStream().use{ it.reader().readText() } }
La autoconversión proporciona un punto de partida, pero se requiere un perfeccionamiento manual significativo y conocimientos de Kotlin para conseguir un Kotlin verdaderamente idiomático.
3. Conversión asistida por IA
Ideal para: bases de código más grandes con una infraestructura de pruebas robusta
Reto:se requiere una revisión manual
La IA puede producir resultados más idiomáticos que la autoconversión básica, pero para obtenerlos se necesita una preparación cuidadosa:
Requisitos previos:
- Amplia cobertura de pruebas: dado que los LLM son impredecibles, necesita pruebas fiables para detectar las alucinaciones de la IA.
- Peticiones al sistema bien elaboradas: cree instrucciones detalladas para conversiones idiomáticas de Kotlin que estén alineadas con sus estándares. Puede utilizar esta petición del sistema como punto de partida.
- Revisión exhaustiva del código: el resultado de la IA requiere una revisión exhaustiva para comprobar la corrección lógica e idiomática, lo que puede resultar mentalmente agotador en el caso de grandes bases de código.
Utilizando la petición del sistema propuesta para guiar la conversión, el resultado es bastante satisfactorio, aunque no perfecto:
Kotlin
fun downloadAndGetLargestFile(urls: List): String? {
val contents = urls
.mapNotNull {
urlStr -> runCatching { URI(urlStr).toURL() }.getOrNull()
}.mapNotNull { url -> runCatching {
url.openStream().use { it.readAllBytes().toString(UTF_8)
}
}.getOrNull() }
return contents.maxOrNull()
}
4. Autoconversión a gran escala
Ideal para: bases de código enormes que requieren una transformación sistemática
Actualmente, no existe ninguna herramienta oficial para convertir bases de código Java a Kotlin idiomático a gran escala. Sin embargo, tanto Meta como Uber han abordado con éxito este reto para sus bases de código de Android utilizando enfoques que funcionan igual de bien para las aplicaciones de backend. Los siguientes documentos y charlas ofrecen una visión de cómo Meta y Uber abordan esta búsqueda:
El enfoque de Meta:

- Estrategia: transformación determinista basada en reglas
- Recursos:
El enfoque de Uber:

- Estrategia: transformación determinista basada en reglas que utiliza la IA para generar las reglas de conversión
- Recurso: Presentación en la KotlinConf
Ambas empresas tuvieron éxito creando procesos sistemáticos y repetibles en lugar de confiar en la conversión manual o en la simple automatización. Sus enfoques basados en reglas garantizan la coherencia y la calidad en millones de líneas de código.
Importante: La conversión de Java a Kotlin a gran escala introduce un reto a nivel organizativo: para que sea fiable, sigue siendo necesario que haya una persona en el proceso revisando el código generado. Sin embargo, si no se planifica con cuidado, los ingenieros pueden verse fácilmente desbordados por la avalancha de solicitudes de incorporación de cambios resultantes de la conversión automatizada. Por lo tanto, es necesario considerar cuidadosamente el impacto en la organización.
Recuerde que el éxito de la adopción de Kotlin a gran escala no consiste únicamente en convertir el código, sino también en desarrollar la experiencia del equipo, establecer normas de codificación y crear procesos sostenibles que aporten valor a largo plazo a su organización.
Breve recapitulación sobre cuándo utilizar cada enfoque:
- ¿Pequeña aplicación o aplicación que se está reescribiendo?
→ Reescribir en Kotlin (1) - ¿Bases de código medianas con tiempo dedicado a la refactorización o un equipo aprendiendo Kotlin?
→ Autoconversión de IntelliJ IDEA + refinamiento (empezar primero con las pruebas) (2) - ¿Código de tamaño medio/grande con patrones repetidos y buenas pruebas?
→ Enfoque asistido por IA (3) - ¿Migración de toda la organización a Kotlin a través de muchos servicios?
→ Autoconversión a escala con un plan concreto (basado en la plataforma) (4)
Desencadene todo el potencial de Kotlin
Kotlin hace que los desarrolladores sean productivos rápidamente. Su sintaxis concisa, sus funcionalidades de seguridad y su rica biblioteca estándar ayudan a muchos desarrolladores a escribir mejor código en cuestión de semanas, a menudo mediante autoaprendizaje o aprendizaje en el puesto de trabajo. Pero sin orientación, muchos caen en la trampa de utilizar Kotlin al estilo Java: ciñéndose a estructuras mutables, patrones verbales y perdiéndose funcionalidades idiomáticas.
Pasar al siguiente nivel
El paso al siguiente nivel (adoptar la inmutabilidad, el código orientado a expresiones, los DSL y la concurrencia estructurada con corrutinas, con o sin hilos virtuales) es donde muchos desarrolladores se atascan.
A estas alturas, he descubierto que la formación externa marca una diferencia mucho mayor que el autoaprendizaje. Incluso a los desarrolladores con años de experiencia en Kotlin les suele venir bien una formación específica para adoptar patrones idiomáticos y liberar todo el potencial del lenguaje.

Kotlin o no Kotlin, esa es la cuestión. ¿Qué tipo de empresa quiere ser?
En última instancia, la decisión de adoptar Kotlin refleja su cultura de ingeniería. Usted prefiere:
- ¿El enfoque tradicional (Java): conservador, ceremonial, estable?
- ¿El enfoque progresivo (Kotlin): pragmático, moderno, adaptativo?
Ambos tienen sus méritos. Java hará el trabajo. Kotlin probablemente lo hará mejor, con desarrolladores más contentos y menos errores. La cuestión no es si Kotlin es mejor, sino si su organización está preparada para invertir en ser mejor.
El camino desde esa primera prueba de Kotlin hasta su adopción en toda la organización no siempre es fácil, pero con el enfoque adecuado, es notablemente predecible. Empiece poco a poco, demuestre su valor, cree una comunidad y escale poco a poco.
Sus desarrolladores —actuales y futuros— se lo agradecerán.
Artículo original en inglés de:
