Novedades en Java

A partir de JDK 9, Java se actualiza con una nueva versión cada 6 meses. Las versiones LTS (Long-Term-Support) como Java 8/11 salen cada tres años y se van actualizando hasta
la siguiente versión LTS.

Desplegar las aplicaciones en contenedores facilita la actualización la versión de Java porque solo hay que actualizar la imagen para incluir un nuevo JDK y
no es necesario reinstalar el JDK en muchos equipos.

Java 9

Sistema modular (proyecto Jigsaw)

El sistema modular introducido en Java 9, probablemente el mayor cambio en la plataforma desde su inicio, proporciona capacidades similares al sistema OSGi.

Ahora es posible, pero no obligatorio, crear software compuesto por módulos que declaran una API pública y establecen relaciones de dependencia con otros módulos.Un módulo tiene un nombre, incluye una lista de paquetes de acceso público y puede incluir la declaración de dependencias hacia otros módulos. A partir de Java 9, todas las clases que son parte del classpath pero que no son parte de un paquete incluido en algún módulo, forman un módulo con nombre ‘unnamed’ que implícitamente depende de todos los módulos incluidos en el JDK.

Este enfoque modular ha sido aplicado a la librería estándar para facilita su evolución/mantenimiento permitiendo eliminar módulos/paquetes considerados obsoletos en lugar de incrementar permanentemente el número de paquetes a medida se publican nuevas versiones de Java.

A la hora migrar un proyecto basado en un JDK monolítico (Java 8 o anterior) a JDK modularizado (Java 9 o posterior) podemos encontrar dos problemas:

  • El proyecto depende de clases que ahora han sido encapsuladas (esos paquetes son ahora privados). En este escenario se debe actualizar el código y las librerías del proyecto con el apoyo de herramientas como jdeps y maven(mvn versions:display-dependency-updates)
  • El proyecto depende de clases en paquetes que no son parte los módulos incluidos por defecto (aquellos incluidos como dependencia del módulo java.se).

En el siguiente vídeo se explica cómo abordar estos problemas.

API para gestión de procesos

El API de procesos se ha mejorado el control y gestión de procesos del sistema operativo. Las nuevas clases que son parte de esta mejora son java.lang.ProcessHandle, java.lang.ProcessHandle.Info

Flow API

La clase java.util.concurrent.Flow incluye interfaces que soportan el framework Reactive Streams. El propósito de estas interfaces es facilitar la interoperabilidad o migración entre varias implementaciones como RxJava, AkkaStreams o Spring Project Reactor.

StackWalker/StackFrame

Clases que facilitan el acceso y análisis de los elementos en la pila de llamadas.

JShell

Entorno interactivo (REPL) similar a los incluidos en lenguages como Python o Scala. Permite evaluar declaraciones y expresiones de Java, junto con una API.
Es muy conveniente para probar pequeños fragmentos de código, que de lo contrario requieren la creación de una nueva clase con el método principal.

Mejoras en APIs existentes

  • Collections, métodos factory para crear instancias inmutables: List.of, Set.of y Map.of, Map.ofEntries
  • Streams, Stream.ofNullable, Stream.takeWhile, Stream.dropWhile
  • Optional, Optional.or, Optional.stream
  • try-with-resources, ya no requiere la declaración de una variable (siempre que esa sea final o efectivamente final).
  • Programación genérica, el operador <> ahora se puede emplear con clases anónimas (anonymous inner classes).
  • Interfaces, pueden tener métodos privados para facilitar la reutilización de código en los métodos default.
  • java.time, Duration.truncatedTo, LocalDate.datesUntil

Referencias

New Features in Java 9

Multi-Release Jar Files

Java 10

Inferencia del tipo de datos para variables locales (var)

Permite emplear el tipo var para inferir el tipo de una variable a partir de lado derecho de una asignación. Debe emplearse siempre que el tipo de dato de la expresión en el lado derecho en una asignación sea evidente; es decir, en situaciones en las que mencionar el tipo de dato en la declaración de la variable es redundante.

Application Class-Data Sharing (ACDS)

En Java 10+, esta funcionalidad permite reducir al tiempo de arranque de la JVM cargando las clases directamente desde un archivo. Los arranques posteriores de la JVM o de otras JVMs que corran la misma aplicación requerirán menos tiempo.

Detección de contenedor

La JVM puede detectar si se ejecuta en un contenedor Docker y es capaz de extraer la configuración específica del contenedor en lugar de consultar el sistema operativo; se aplica a métricas como la cantidad de CPUs y la memoria total asignadas al contenedor. Sin embargo, este soporte solo está disponible para plataformas basadas en Linux.

Referencias

OpenJDK 10 Now Includes Root CA Certificates

New Features in Java 10

Java 10 LocalVariable Type-Inference

Java 10 Performance Improvements

Java 11

Herramientas

Java Flight Recorder (JFR) y JDK Mission Control (JMC) ahora son herramientas Open Source. JFR es una herramienta para realizar profiling sobre el desempeño y uso de recursos de una aplicación Java. Por ejemplo, para iniciar una grabación JFR de 120 segundos, podemos usar el siguiente parámetro al iniciar Java

-XX:StartFlightRecording=duration=120s,settings=profile,filename=java-demo-app.jfr

Se puede emplear JFR en producción puesto que la carga general suele ser inferior al 1%. Una vez transcurrido el tiempo, podemos emplear JMC para analizar y visualizar los dato del archivo JFR.

Ejecución de archivos Java.

Ya no es necesario compilar un archivo Java antes de ejecutarlo.

HttpClient API

Ofrece un API para establecer conexiones síncronas y asíncronas empleando HTTP/1.1, HTTP/2 o WebSockets. Clases importantes:

  • HttpClient/HttpClient.Builder
  • HttpRequest/HttpRequest.Builder
  • HttpResponse

Mejoras en APIs existentes

  • Eliminación de los siguientes paquetes:
    • java.xml.bind (JAXB)
    • java.xml.ws (JAX-WS)
    • java.xml.ws.annotation (JAX-WS Annotations)
    • java.corba (CORBA)
    • java.transaction (JTA)
    • java.activation (JavaBeans Activation)
  • Eliminación de los siguientes métodos:
    • Thread.destroy
    • Thread.stop(Throwable obj)
    • System.runFinalizersOnExit
    • Runtime.System.runFinalizersOnExit
  • JavaFX ya no es parte del SDK y debe ser incluido como dependencia de manera explícita.
  • Applets y Java Web Start ya no son parte de JDK.
  • String, se agregaron los siguientes métodos: isBlank, lines, strip (soporta caracteres del espacio Unicode), stripLeading, stripTrailing y repeat.
  • Files, se agregaron los siguientes métodos: Files.readString, Files.writeString para facilitar la lectura/escritura de archivos de texto.
  • Programación funcional: Predicate.not, Optional.isEmpty.

Referencias

New Features in Java 11

Java 12

Formato de número compacto

La clase CompactNumberFormat está diseñada para representar un número en una forma más corta, basada en los patrones proporcionados por una Locale determinado.

Mejoras en APIs existentes

  • String: nuevos métodos indent, transform
  • Files: Files.mismatch compara dos archivos y retorna la posición del primer byte no coincidente en su contenido.
  • Programación funcional: Collectors.teeing permite aplicar dos collectors al mismo tiempo y combinar sus resultados.

Java Micro-benchmarking harness (JMH)

El alcance o nivel del micro benchmarking empleando esta herramienta está al nivel de los métodos y permite comparar alternativas para tomar la mejor decisión de diseño en secciones de código que se ejecutan con mucha frecuencia y tomar decisiones en aspectos como los siguientes:

  • Apoyarse en el garbage collector o emplear pooling (reusar objectos)
  • Atrapar un error o verificar el estado antes de ejecutar una sección de código. (if vs. try-catch)
  • Evitar regresiones en el desempeño de métodos críticos y seleccionar las implementación con el mejor desempeño.

Puede crear un proyecto basado en JMH empleando el siguiente arquetipo Maven:

mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=org.openjdk.jmh -DarchetypeArtifactId=jmh-java-benchmark-archetype -D<group-id> -DartifactId=<artifact-id> -Dversion=1.0

Como se muestra en el siguiente vídeo, las pruebas de desempeño se configuran empleando anotaciones:

Referencias

New Features in Java 12

Compact Number Formatting Comes to JDK 12

Microbenchmarking with Java

Testing your code performance with JMH tool

Java 13

Mejoras en APIs existentes

  • ByteBuffer: es una clase empleada en la API Java NIO. En Java 13 esta clase incluye mejoras en los métodos get y put que hora soportan
    el parámetro index que abre la posibilidad de leer/modificar la estructura desde varios hilos en lugar de sincronizar
    el acceso al ByteBuffer.
  • Seguridad: javax.security.cert fue eliminado y las clases movidas a javax.security.cert
  • Localización: soporte de Unicode 12.1.
  • Mantenimiento: reimplementación del API de sockets ((java.net.Socket, java.net.ServerSocket). Si por alguna razón esto causa algún inconveniente es posible
    emplear por algún tiempo más la implementación antigua pasando esta propiedad del sistema -Djdk.net.usePlainSocketImpl

Class-Data Sharing Dinámico (D-CDS)

Se introdujeron dos mejoras a esta funcionalidad introducida en Java 10:

Se facilita la creación de los archivos con la metadata de las clases que se quieren pre-cargar al iniciar la VM.
El siguiente comando configura la JVM para guardar en el archivo hello.jsa la metadata de las clases Cuando la aplicación termine sin errores (exit code = 0):

java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello

Para cargar los archivos en otra JVM que corra con el mismo classpath:

java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello

Referencias

New Features in Java 13

Java NIO – Using ByteBuffer

Java 14

Mejoras en APIs existentes

  • PrintStream, se agregaron los siguientes métodos: writeBytes
  • Serialización: se agregó una nueva anotación @java.io.serial para la verificación en tiempo de compilación de declaraciones
    relacionadas con la serialización.
  • Mantenimiento: se eliminó el paquete java.security.acl y se eliminaron las clases
    java.util.jar.Pack200.Packer y java.util.jar.Pack200.Unpacker.

Mensajes NullPointerException más detallados

Incluyendo la opción de línea de comando -XX:+ShowCodeDetailsInExceptionMessages es posible generar información más detallada cuando se produce un NullPointerException. Los mensajes generados son todavía más informativos cuando la compilación incluye la
opción para incluir más datos/símbolos de depuración (javac -g)

En la parte inferior de la siguiente imagen se puede ver que el mensaje generado en Java 14+ incluye más detalles sobre la causa del error.

Expresiones switch

Introducidas en modo preliminar/preview en la versión 12, esta nueva característica del lenguaje permite emplear estructuras switch para crear expresiones; es decir, para generar un valor que puede ser asignado a una variable, pasado como argumento o devuelto a/desde un método.

    private static String platoADepartamento(String plato) {
        return switch (plato.strip().toLowerCase()) {
            case "soltero", "sullka", "karapecho", "mondongo" -> "Chuquisaca";
            case "pique", "chajchu", "pampaku" -> "Cochabamba";
            case "chairo", "fricasé" -> "La Paz";
            case "charque" -> "Oruro";
            case "majadito" -> "Santa Cruz";
            case "saice" -> "Tarija";
            default -> "desconocido";
        };
    }

Datos en tiempo real desde Java Flight Recorder

Con esta mejora, los datos generados por JFR se pueden consumir/monitorear continuamente. Esto implica modificaciones en el paquete jdk.jfr.consumer para que los usuarios puedan leer o transmitir datos directamente de sde/hacia JFR.

Referencias

New Features in Java 14

Java 15

Mejoras a APIs existentes

  • PrintStream, se agregaron los siguientes métodos: writeBytes
  • Serialización: se agregó una nueva anotación @java.io.serial para la verificación en tiempo de compilación de declaraciones
    relacionadas con la serialización.
  • Mantenimiento: se ha eliminado el soporte para plataformas Solaris/SPARC y el entorno de ejecución de JavaScript Nashorn para el cual existen algunas alternativas.

Mensajes NullPointerException más detallados

En Java 15 ya no es necesario incluir la opción de línea de comando -XX:+ShowCodeDetailsInExceptionMessages para activar esta funcionalidad.

Bloques de texto

Introducidas en modo preliminar/preview en la versión 13, esta nueva característica del lenguaje permite emplear cadenas de texto que se extienden por varias líneas directamente en el código fuente sin necesidad de incluir explícitamente caracteres de fin de línea y/o emplear concatenación de cadenas. Cuando el compilador detecta una cadena multi-línea en el código fuente, aplica ciertas transformaciones como la normalización del caracter de fin de línea y la eliminación de espacios innecesarios para que la cadena resultante sea la misma independientemente de la plataforma en la que se crea el código.

El caracter diagonal invertida/backslash puede emplearse para generar una cadena de una sola línea pero empleando varias líneas en el código fuente.

Finalmente, la clase String incluye nuevos métodos relacionados con manejo de bloques de texto: translateEscapes, stripIndent y formatted.

String jsonString = """
    {
          "nombre": "Marcelo",
          "apellido": "%s"
    }
    """.formatted("Rocabado");

Nuevos Recolectores de basura (Garbage Collectors)

En Java 15, tanto ZGC (JEP 377) como Shenandoah (JEP 379) dejarán de ser experimentales. Ambos recolectores están disponibles para su uso en producción, pero el recolector G1 seguirá siendo el predeterminado.

ZGC garantiza pausas de menos de 10ms en aplicaciones con memoria heap en el rango de 8Mb – 16TB!.

Referencias

What’s New in Java 15

Programmer’s Guide To Text Blocks

Understanding the JDK’s New Superfast Garbage Collectors

A categorized list of all Java and JVM features since JDK 8 to 16

Ripe for the picking: 11 essential Java features to help modernize your code

Comments are closed.