Más de tres años después del lanzamiento de Java 8, la próxima versión está a la vuelta de la esquina con una fecha de lanzamiento tentativa del 21 de septiembre de 2017. Puede que hayan oído hablar del sistema de módulos de Java 9, pero hay aún más en esta nueva versión. Aquí hay nueve nuevas y emocionantes características que se enviarán con Java 9.
1. El sistema de módulos de la plataforma Java
La característica que define a Java 9 es un sistema de módulos completamente nuevo. Cuando las bases de código crecen, las probabilidades de crear un complicado y enmarañado «código espagueti» aumentan exponencialmente. Hay dos problemas fundamentales: Es difícil encapsular realmente el código, y no existe la noción de dependencias explícitas entre las diferentes partes (archivos JAR) de un sistema. A cada clase pública se puede acceder por cualquier otra clase pública en el classpath, lo que lleva a un uso inadvertido de clases que no estaban destinadas a ser una API pública. Además, el classpath en sí mismo es problemático: ¿Cómo se sabe si están todos los JAR necesarios o si hay entradas duplicadas? El sistema de módulos aborda ambos problemas.
Los archivos modulares JAR contienen un descriptor adicional del módulo. En este descriptor de módulo, las dependencias de otros módulos se expresan mediante declaraciones de requisitos. Además, las declaraciones `exports` controlan qué paquetes son accesibles para otros módulos. Todos los paquetes no exportados están encapsulados en el módulo por defecto. Aquí hay un ejemplo de un descriptor de módulo, que vive en `module-info.java`:
modulo blog { exportaciones com..blog; requiere cms;}
Podemos visualizar los módulos de la siguiente manera:
Observe que ambos módulos contienen paquetes que están encapsulados porque no se exportan (visualizados con el escudo naranja). Nadie puede usar accidentalmente clases de esos paquetes. La propia plataforma Java ha sido modularizada usando su propio sistema de módulos también. Al encapsular las clases internas del JDK, la plataforma es más segura y evolucionarla se hace mucho más fácil.
Al iniciar una aplicación modular, la JVM verifica si todos los módulos pueden ser resueltos en base a las declaraciones de «requiere», un gran paso adelante de la frágil classpath. Los módulos le permiten estructurar mejor su aplicación con una fuerte aplicación de encapsulación y dependencias explícitas. Puedes aprender más sobre el trabajo con módulos en Java 9 con este curso.
2. Vinculación
Cuando se tienen módulos con dependencias explícitas, y un JDK modularizado, surgen nuevas posibilidades. Sus módulos de aplicación ahora establecen sus dependencias con otros módulos de aplicación y con los módulos que utiliza del JDK. ¿Por qué no utilizar esa información para crear un entorno de ejecución mínimo, que contenga sólo los módulos necesarios para ejecutar su aplicación? Eso es posible con la nueva herramienta jlink en Java 9. En lugar de enviar su aplicación con una instalación JDK completamente cargada, puede crear una imagen de tiempo de ejecución mínima optimizada para su aplicación.
3. JShell: el interactivo Java REPL
Muchos lenguajes ya cuentan con un bucle interactivo de lectura-evaluación-impresión, y Java se une ahora a este club. Puedes lanzar jshell desde la consola y empezar directamente a escribir y ejecutar código Java. La respuesta inmediata de jshell lo convierte en una gran herramienta para explorar las API y probar las características del lenguaje.
Probar una expresión regular de Java es un gran ejemplo de cómo jshell puede hacerte la vida más fácil. El shell interactivo también es un gran entorno de enseñanza e impulso de la productividad, que puede conocer más en este seminario web. Ya no tienes que explicar de qué se trata esta tontería del «vacío estático público principal (String[] args)` cuando se enseña a la gente a programar Java.
4. Javadoc mejorado
A veces son las pequeñas cosas las que pueden hacer una gran diferencia. ¿Usaste Google todo el tiempo para encontrar las páginas de Javadoc adecuadas, como yo? Eso ya no es necesario. Javadoc ahora incluye la búsqueda directamente en la propia documentación de la API. Como un bono adicional, la salida de Javadoc ahora es compatible con HTML5. Además, notarás que todas las páginas de Javadoc incluyen información sobre el módulo JDK del que proviene la clase o la interfaz.
5. Métodos de fábrica de recolección
A menudo se quiere crear una colección (por ejemplo, una lista o conjunto) en su código y poblarla directamente con algunos elementos. Eso lleva a un código repetitivo donde instanciar la colección, seguido de varias llamadas «add». Con Java 9, se han añadido varios métodos llamados «fábrica de colecciones»:
Set<Integer> ints = Set.of(1, 2, 3);List<String> strings = List.of("first", "second");
Además de ser más cortos y más agradables de leer, estos métodos también le liberan de tener que elegir una implementación de recolección específica. De hecho, las implementaciones de recolección devueltas de los métodos de fábrica están altamente optimizadas para el número de elementos que pones. Eso es posible porque son inmutables: añadir elementos a estas colecciones después de la creación resulta en una «excepción de operación no soportada».
6. Mejoras en el API del flujo
El API de Streams es posiblemente una de las mejores mejoras de la biblioteca estándar de Java en mucho tiempo. Permite crear tuberías declarativas de transformaciones en las colecciones. Con Java 9, esto sólo se mejora. Hay cuatro nuevos métodos añadidos a la interfaz de Stream: dropWhile, takeWhile, ofNullable. El método de iteración tiene una nueva sobrecarga, permitiéndote proporcionar un predicado de cuándo parar de iterar:
IntStream.iterate(1, i -----; i < 100, i -----; i + 1).forEach(System.out::println);
El segundo argumento es un lambda que vuelve a la realidad hasta que el elemento actual en el IntStream se convierte en 100. Por lo tanto, este simple ejemplo imprime los números enteros del 1 al 99 en la consola.
Además de estas adiciones en el propio Stream, se ha mejorado la integración entre Opcional y Stream. Ahora es posible convertir un objeto Opcional en un Arroyo (posiblemente vacío) con el nuevo método «Arroyo» en Opcional:
Stream<Integer;s = Opcional.de(1).stream();
Convertir una opción en un arroyo es especialmente útil cuando se componen complejas tuberías de arroyo.
7. Métodos de interfaz privada
Java 8 nos trajo métodos por defecto en las interfaces. Una interfaz ahora también puede contener comportamiento en lugar de sólo firmas de métodos. ¿Pero qué pasa si tienes varios métodos por defecto en una interfaz con código que hace casi lo mismo? Normalmente, refactorizarías esos métodos para llamar a un método privado que contenga la funcionalidad compartida. Pero los métodos predeterminados no pueden ser privados. Crear otro método predeterminado con el código compartido no es una solución, porque este método de ayuda pasa a formar parte de la API pública. Con Java 9, se pueden añadir métodos privados de ayuda a las interfaces para resolver este problema:
interfaz pública MyInterface { void normalInterfaceMethod(); default void interfaceMethodWithDefault() { init(); } default void anotherDefaultMethod() { init(); } // Este método no es parte de la API pública expuesta por MyInterface private void init() { System.out.println("Initializing"); }}
Si está evolucionando las API con métodos predeterminados, los métodos de interfaz privada pueden ser útiles para estructurar su implementación.
8. HTTP/2
Una nueva forma de realizar llamadas HTTP llega con Java 9. Esta muy atrasada sustitución de la antigua API «HttpURLConnection» también soporta WebSockets y HTTP/2 fuera de la caja. Una advertencia: El nuevo API de HttpClient se entrega como un llamado _módulo incubador_ en Java 9. Esto significa que el API no está garantizado a ser 100% final todavía. Aún así, con la llegada de Java 9 ya se puede empezar a utilizar esta API:
HttpCliente cliente = HttpCliente.newHttpCliente();HttpRequest req = HttpRequest.newBuilder(URI.create("http://www.google.com")) .header("User-Agent", "Java") .GET() .build();HttpResponse<String> resp = cliente.send(req, HttpResponse.BodyHandler.asString());
Además de este sencillo modelo de solicitud/respuesta, HttpClient proporciona nuevas APIs para tratar con las características de HTTP/2 como los flujos y el empuje del servidor.
9. JARs de multi-lanzamiento
La última característica que estamos destacando es una noticia especialmente buena para los mantenedores de la biblioteca. Cuando sale una nueva versión de Java, todos los usuarios de su biblioteca tardan años en cambiar a esta nueva versión. Eso significa que la biblioteca tiene que ser compatible con la versión más antigua de Java que se desea apoyar (por ejemplo, Java 6 o 7 en muchos casos). Esto significa que no podrá utilizar las nuevas características de Java 9 en su biblioteca durante mucho tiempo. Afortunadamente, la característica JAR de múltiples versiones le permite crear versiones alternativas de clases que sólo se utilizan cuando se ejecuta la biblioteca en una versión específica de Java:
multirelease.jar├─── META-INF│ └── versions│ └── 9│ └── multirelease│ └── Helper.class├─── multirelease ├── Helper.class └─── Main.class
En este caso, se puede utilizar el multirelease.jar en Java 9, donde en lugar de la clase multirelease.Helper de nivel superior, se utiliza la de `META-INF/versions/9`. Esta versión de la clase específica de Java 9 puede utilizar las características y bibliotecas de Java 9. Al mismo tiempo, el uso de este JAR en versiones anteriores de Java sigue funcionando, ya que las versiones anteriores de Java sólo ven la clase Helper de nivel superior.
Como pueden ver, Java 9 ofrece una amplia gama de nuevas características, tanto pequeñas como grandes. ¿Listo para empezar?
Aprende más: Modularidad de Java 9: First Look
COMPARTIR: