Índice
- Las «edades» de Java
- El ciclo actual de release de Java
- El proceso para añadir funcionalidad a una versión de Java
- Conclusión
Java 23 ya está disponible desde el 17 de septiembre de 2024. Como siempre que se lanza una nueva versión, es útil conocer las novedades que incluye nuestro lenguaje favorito. Y, como primera aportación para este nuevo sitio web, parece un buen momento para escribir un artículo repasando las novedades que trae esta versión de Java.
Sin embargo, si echamos un vistazo a la página dedicada a la release de openJDK 23, vemos que muchas de las funcionalidades que incorpora aparecen marcadas con etiquetas como «Incubator, Preview o Second Preview».
- 455: Primitive Types in Patterns, instanceof, and switch (Preview)
- 466: Class-File API (Second Preview)
- 467: Markdown Documentation Comments
- 469: Vector API (Eighth Incubator)
- 473: Stream Gatherers (Second Preview)
- 471: Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal
- 474: ZGC: Generational Mode by Default
- 476: Module Import Declarations (Preview)
- 477: Implicitly Declared Classes and Instance Main Methods (Third Preview)
- 480: Structured Concurrency (Third Preview)
- 481: Scoped Values (Third Preview)
- 482: Flexible Constructor Bodies (Second Preview)
Por esta razón, y antes de entrar en los detalles de esas funcionalidades (lo que haré en un segundo artículo más específico), esta versión es una buena oportunidad para comenzar a introducir algunos conceptos sobre cómo está diseñado el proceso de lanzamiento de Java, la evolución del lenguaje y la plataforma, y los beneficios que el ciclo de lanzamientos actual de Java aporta a los desarrolladores y a la comunidad de lenguajes JVM en general.
Las “edades” de Java
Empecemos por una visión personal y general para poner en contexto la evolución histórica de Java y entender y valorar su situación actual.
En el mundo del desarrollo de software, el lenguaje de programación Java ha sido un pilar fundamental desde su creación en 1995. Durante todos estos años, hemos visto cómo Java ha ido evolucionando y adaptando el proceso de añadir nuevas funcionalidades y de liberar nuevas versiones para tratar de que los desarrolladores podamos ir probando e incorporando a nuestra forma de desarrollar los últimos cambios.
Más allá del detalle de las funcionalidades y las fechas, si echamos un vistazo a la cronología de las distintas versiones y tipos de releases, a mí me gusta pensar que se puede identificar cómo Java ha ido madurando hasta en la forma de evolucionar.
Personalmente, me gusta ver el paralelismo entre la evolución de Java y la evolución de las personas. Así, examinando el gráfico anterior con la línea de vida de Java, a mi me gusta identificar tres etapas diferentes: la niñez, la adolescencia y la juventud/madurez de Java.
De forma breve, a mi me gusta visualizarlo y explicarlo de la siguiente forma: La evolución de Java se puede dividir en tres fases: (recuerda que esta clasificación es una visión personal mía, no es nada estandarizado, pero se basa en mi percepción de cómo he vivido y experimentado todos estos cambios en la evolución de Java).
- Infancia (1995-2004): La historia de Java comienza con su primera versión: la 1.0, lanzada en 1996. A partir de ahí, el lenguaje fue evolucionando con nuevas versiones como la 1.1, la 1.2, la 1.3, y la 1.4, incorporando mejoras y nuevas funcionalidades. Este período estuvo marcado por la popularidad y un uso creciente de Java en la industria.
- Adolescencia (2004-2016): Java 5 marcó un punto de inflexión significativo con la introducción de características como los genéricos y las importaciones estáticas, entre otras. Sin embargo, la transición de Java 6 a Java 7 fue lenta, con un intervalo de cinco años entre lanzamientos. Este periodo estuvo lleno de desafíos a medida que se introducían nuevas funcionalidades y la modularidad comenzó a cobrar importancia con la llegada de Java 9.
- Juventud y madurez (2016-presente): Con la llegada de Java 9, se estableció un nuevo ritmo de lanzamientos, con la idea de poder liberar nuevas funcionalidades dos veces por año. Este cambio se formalizó en el concepto de “feature releases”, donde se planea el lanzamiento de nuevas características en marzo y septiembre, además de actualizaciones de seguridad y correcciones de errores en trimestres alternos.
Si tienes curiosidad por este paralelismo, puedes verlo en los 10 minutos iniciales de la charla “Novedades de Java 21” que dimos varios miembros de MadridJUG en abril de 2022.
El ciclo actual de release de Java
Actualmente, y desde abril de 2017, la planificación de las versiones de Java se basa en un ciclo de seis meses, por lo que cada marzo y septiembre se lanza una nueva versión de la plataforma.
Esto ha permitido que Java mantenga su relevancia, adaptándose e incorporando nuevas funcionalidades demandadas por los desarrolladores. Al mismo tiempo, nos permite a los desarrolladores ir probando y adoptando nuevas características y mejoras de una forma más progresiva y ágil, en contraste con el ciclo anterior, en el que los lanzamientos eran mucho más espaciados y teníamos que esperar mucho más tiempo para poder utilizar nuevas funcionalidades del lenguaje y de la plataforma.
Aun así, no todas las versiones son iguales en términos de soporte y estabilidad.
Versiones LTS y non-LTS
Las versiones LTS (Long-Term Support) son aquellas que reciben soporte a largo plazo, generalmente cada dos años. Son las versiones recomendadas para entornos de producción estables. Actualmente, Java 21 es la última versión LTS disponible, y la próxima será Java 25. Las versiones LTS reciben actualizaciones de seguridad y correcciones de errores durante varios años.
Las versiones non-LTS: son las que se liberan entre las versiones LTS y que tienen, en principio, sólo soporte hasta la siguiente versión. No obstante, el soporte concreto depende de la política que establezca el distribuidor del binario del JDK.
Creo que este punto merece la pena detenerse un poco y aclararlo.
Sobre el tema de las versiones LTS o no LTS, hay que matizar que la versión del lenguaje Java (de su especificación), por sí misma, no es ni deja de ser LTS. Lo que es LTS o no LTS es la liberación del binario de JDK que se libera correspondiendo con una versión de Java.
Existen varias distribuciones binarias del JDK, cada una de las cuales es responsabilidad de la compañía o entidad que la libera y la distribuye: Así, Oracle libera OracleJDK; Adoptium es la entidad, perteneciente a Eclipse Foundation, que libera los binarios de OpenJDK; Azul Systems tiene sus propias releases del JDK; Amazon con Corretto; ….
En resumen, la característica de LTS en realidad aplica a las distribuciones binarias que se liberan por cada una de estas entidades. No obstante, la recomendación es que al menos, los binarios de JDK correspondientes a las versiones de java que se liberan cada dos años, sean marcadas como LTS
Si quieres una explicación un poco más detallada (en inglés) de este razonamiento, puedes echar un vistazo a este video que publicó Nicolai Parlog cuando se liberó Java 21 explicando que Java 21 no es LTS, sino los binarios de JDK 21.
Screenshot from Nicolai’s Video explaining why Java itself can’t be LTS, but the binary releases of the JDK
¿Es Java 23 una version LTS? La respuesta es no, la última versión LTS de Java corresponde con Java 21, que se liberó en septiembre de 2022. Por tanto, la próxima versión Java LTS será la que se liberará en Septiembre de 2025, que corresponde con Java 25.
El proceso para añadir funcionalidad a una versión de Java
Con el nuevo ciclo de versiones que se estableció con Java 9 a principios de 2017, también se organizó la forma en la que se incorporan nuevas funcionalidades a una nueva versión de Java.
El proceso para introducir nuevas funcionalidades en Java se organiza a través de JDK Enhancement Proposals (JEPs). Cualquier desarrollador puede proponer una nueva funcionalidad y estas propuestas se revisan y agrupan en proyectos específicos, dependiendo de su impacto en el rendimiento, la sintaxis y otros aspectos del lenguaje.
Así, por ejemplo, tenemos el proyecto Valhalla (que agrupa JEPs que afectan el sistema de clases y tipos en el lenguaje Java), el proyecto Panama (que agrupa los JEPs que afectan a la interacción entre Java y APIs nativas), el proyecto Amber (que recoge funcionalidades que afectan a la sintáxis del lenguaje)….
Estado de las funcionalidades (JEPs) en una versión de Java
Cada una de las funcionalidades (o JEPs) se incorporan a una versión cuando su estado de desarrollo ha alcanzado un estado de madurez mínimo. No obstante, ese estado determina el grado de disponibilidad (y las condiciones para utilizarlo) por parte de los desarrolladores.
Este estado es el que veíamos marcado entre paréntesis en la lista inicial de funcionalidades de Java 23. Ahora entenderemos un poco mejor las implicaciones de dichos estados.
Así, podemos tener marcadas las funcionalidades de una determinada versión de Java como:
Incubator
La funcionalidad aún está en desarrollo y no se considera estable. Se publica en este estado cuando el equipo de desarrollo decide permitir que los desarrolladores podamos empezar a experimentar y probar con la funcionalidad.
Sin embargo, el API no es estable y puede cambiar significativamente entre dos releases, lo que implica que se podría romper cualquier código que hayamos escrito utilizando esa funcionalidad.
Tampoco existe ningún tipo de límite en el número de iteraciones que la funcionalidad puede aparecer en modo Incubator. De hecho, El JEP 469 correspondiente a “Vector API” va ya por la octava iteración en modo Incubator.
El hecho de que una funcionalidad se publique en una versión en modo “Incubator”, tampoco implica que vaya a alcanzar el estado “Final” en un futuro: podría darse el caso de que, después de algunas releases y de recibir feedback, el equipo decida retirar la funcionalidad y no incorporarla oficialmente a Java, o que decida sustituirla por otro JEP que aborde esa funcionalidad de una forma alternativa.
Preview
Cuando se considera que una funcionalidad (un JEP) ya está estable en su diseño y está cerca de ser liberada, se puede añadir a la release en modo “Preview”.
Un JEP en modo preview indica que se considera que el API no va a tener cambios o, al menos, no va a tener cambios significativos, y que puede empezar a utilizarse en determinados casos. Aunque puede haber alguna a excepción, y de hecho, con Java 23 y los String Templates tenemos una de esas excepciones, pero hablaremos de esto en otro artículo posterior.
Para poder utilizar las funcionalidades en modo preview es necesario habilitarlo de forma específica, añadiendo el argumento –enable-preview tanto al invocar el compilador javac como al arrancar la JVM con el comando java
El objetivo de añadir un JEP en modo Preview a la release de Java es permitir a los desarrolladores utilizar su funcionalidad y asegurar que el rendimiento es el esperado y asegurar que no existen bugs o casos límite no controlados en su uso.
En principio, una funcionalidad liberada en JEP tiene el compromiso de que alcanzará su estado Final en un máximo de tres releases (en teoría un JEP solo puede llegar hasta Third Preview antes de pasar a estado Final), o lo que es lo mismo, que en un máximo de 2 años se publicará como Final.
Final
La funcionalidad se considera estable y está lista para su uso general y ya está activa por defecto.
Conclusión
Java lleva ya casi 30 años con nosotros (en 2025 celebraremos su trigésimo aniversario) y, a lo largo de este tiempo, ha ido creciendo y adaptando su forma de incorporar nuevas funcionalidades. En la actualidad, estas se incorporan de forma más progresiva y constante.
Con el nuevo ciclo de lanzamientos, Java ha alcanzado una madurez que permite que tanto el lenguaje como la plataforma vayan proporcionando nuevas funcionalidades a los desarrolladores y nos permitan seguir utilizando nuestras tecnologías favoritas para afrontar los retos actuales en la construcción de software.
Esta evolución e incorporación constante de funcionalidades, incluso algunas en modo Preview, hacen aún más interesante que podamos actualizar nuestros sistemas e ir evaluando y familiarizándonos con las novedades de forma progresiva.
Por este motivo, aunque no estés pensando en actualizar a la última versión de Java (aunque deberíamos hacerlo en la medida de lo posible), sí que deberíamos instalar al menos la última versión en nuestros entornos de desarrollo (con herramientas como SDKman es muy sencillo cambiar entre varias versiones de Java en el entorno local) e ir probando y adaptando nuestra forma de desarrollar para poder aprovechar siempre toda la potencia del lenguaje.