Nuevas funciones de Java 13

1. Información general

Septiembre de 2019 vio el lanzamiento de JDK 13, según la nueva cadencia de lanzamiento de Java de seis meses . En este artículo, veremos las nuevas funciones y mejoras introducidas en esta versión.

2. Vista previa de las funciones para desarrolladores

Java 13 ha incorporado dos nuevas funciones de lenguaje, aunque en el modo de vista previa . Esto implica que estas características están completamente implementadas para que los desarrolladores las evalúen, pero no están listas para producción. Además, pueden eliminarse o hacerse permanentes en versiones futuras según los comentarios.

Necesitamos especificar –enable-preview como una marca de línea de comandos para usar las funciones de vista previa . Veámoslos en profundidad.

2.1. Cambiar expresiones (JEP 354)

Inicialmente vimos expresiones de cambio en JDK 12. Las expresiones de cambio de Java 13 se basan en la versión anterior al agregar una nueva declaración de rendimiento .

Usando yield , ahora podemos devolver valores de manera efectiva a partir de una expresión de cambio :

@Test @SuppressWarnings("preview") public void whenSwitchingOnOperationSquareMe_thenWillReturnSquare() { var me = 4; var operation = "squareMe"; var result = switch (operation) { case "doubleMe" -> { yield me * 2; } case "squareMe" -> { yield me * me; } default -> me; }; assertEquals(16, result); }

Como podemos ver, ahora es fácil implementar el patrón de estrategia con el nuevo conmutador.

2.2. Bloques de texto (JEP 355)

La segunda función de vista previa son los bloques de texto para cadenas de varias líneas , como JSON, XML, HTML, etc.

Anteriormente, para incrustar JSON en nuestro código, lo declararíamos como un literal de cadena :

String JSON_STRING = "{\r\n" + "\"name\" : \"Baeldung\",\r\n" + "\"website\" : \"//www.%s.com/\"\r\n" + "}";

Ahora escribamos el mismo JSON usando bloques de texto String :

String TEXT_BLOCK_JSON = """ { "name" : "Baeldung", "website" : "//www.%s.com/" } """;

Como es evidente, no hay necesidad de escapar de las comillas dobles ni de agregar un retorno de carro. Al utilizar bloques de texto, el JSON incorporado es mucho más sencillo de escribir y más fácil de leer y mantener.

Además, todas las funciones de String están disponibles:

@Test public void whenTextBlocks_thenStringOperationsWorkSame() { assertThat(TEXT_BLOCK_JSON.contains("Baeldung")).isTrue(); assertThat(TEXT_BLOCK_JSON.indexOf("www")).isGreaterThan(0); assertThat(TEXT_BLOCK_JSON.length()).isGreaterThan(0); } 

Además, java.lang.String ahora tiene tres nuevos métodos para manipular bloques de texto:

  • stripIndent () : imita al compilador para eliminar espacios en blanco incidentales
  • translateEscapes () : traduce secuencias de escape como "\\ t" a "\ t"
  • formatted () : funciona igual que String :: format, pero para bloques de texto

Echemos un vistazo rápido a un ejemplo con formato String :::

assertThat(TEXT_BLOCK_JSON.formatted("baeldung").contains("www.baeldung.com")).isTrue(); assertThat(String.format(JSON_STRING,"baeldung").contains("www.baeldung.com")).isTrue(); 

Dado que los bloques de texto son una función de vista previa y se pueden eliminar en una versión futura, estos nuevos métodos están marcados como obsoletos.

3. Archivos de CDS dinámicos (JEP 350)

El intercambio de datos de clases (CDS) ha sido una característica destacada de Java HotSpot VM desde hace un tiempo. Permite que los metadatos de la clase se compartan entre diferentes JVM para reducir el tiempo de inicio y la huella de memoria . JDK 10 amplió esta capacidad al agregar CDS de aplicaciones (AppCDS), para dar a los desarrolladores el poder de incluir clases de aplicaciones en el archivo compartido. JDK 12 mejoró aún más esta función para incluir archivos CDS de forma predeterminada.

Sin embargo, el proceso de archivar clases de aplicaciones fue tedioso. Para generar archivos de almacenamiento, los desarrolladores tenían que hacer pruebas de sus aplicaciones para crear primero una lista de clases y luego volcarla en un archivo. Después de eso, este archivo podría usarse para compartir metadatos entre JVM.

Con el archivo dinámico, JDK 13 ha simplificado este proceso. Ahora podemos generar un archivo compartido en el momento en que se cierra la aplicación . Esto ha eliminado la necesidad de realizar pruebas.

Para permitir que las aplicaciones creen un archivo compartido dinámico sobre el archivo del sistema predeterminado, debemos agregar una opción -XX: ArchiveClassesAtSalir y especificar el nombre del archivo como argumento:

java -XX:ArchiveClassesAtExit= -cp  AppName

Luego podemos usar el archivo recién creado para ejecutar la misma aplicación con la opción -XX: SharedArchiveFile :

java -XX:SharedArchiveFile= -cp  AppName

4. ZGC: Uncommit Unused Memory (JEP 351)

The Z Garbage Collector was introduced in Java 11 as a low-latency garbage collection mechanism, such that GC pause times never exceeded 10 ms. However, unlike other HotSpot VM GCs such as G1 and Shenandoah, it was not equipped to return unused heap memory to the operating system. Java 13 added this capability to the ZGC.

We now get a reduced memory footprint along with performance improvement.

Starting with Java 13, the ZGC now returns uncommitted memory to the operating system by default, up until the specified minimum heap size is reached. If we do not want to use this feature, we can go back to the Java 11 way by:

  • Using option -XX:-ZUncommit, or
  • Setting equal minimum (-Xms) and maximum (-Xmx) heap sizes

Additionally, ZGC now has a maximum supported heap size of 16TB. Earlier, 4TB was the limit.

5. Reimplement the Legacy Socket API (JEP 353)

We have seen Socket (java.net.Socket and java.net.ServerSocket) APIs as an integral part of Java since its onset. However, they were never modernized in the last twenty years. Written in legacy Java and C, they were cumbersome and difficult to maintain.

Java 13 bucked this trend and replaced the underlying implementation to align the API with the futuristic user-mode threads. Instead of PlainSocketImpl, the provider interface now points to NioSocketImpl. This newly coded implementation is based on the same internal infrastructure as java.nio.

Again, we do have a way to go back to using PlainSocketImpl. We can start the JVM with the system property -Djdk.net.usePlainSocketImpl set as true to use the older implementation. The default is NioSocketImpl.

6. Miscellaneous Changes

Apart from the JEPs listed above, Java 13 has given us a few more notable changes:

  • java.nio – method FileSystems.newFileSystem(Path, Map) added
  • java.time – new official Japanese era name added
  • javax.crypto – support for MS Cryptography Next Generation (CNG)
  • javax.security – property jdk.sasl.disabledMechanisms added to disable SASL mechanisms
  • javax.xml.crypto – new String constants introduced to represent Canonical XML 1.1 URIs
  • javax.xml.parsers – new methods added to instantiate DOM and SAX factories with namespaces support
  • Unicode support upgraded to version 12.1
  • Support added for Kerberos principal name canonicalization and cross-realm referrals

Además, se propone la eliminación de algunas API. Estos incluyen los tres métodos String enumerados anteriormente y la API javax.security.cert .

Entre las eliminaciones se incluyen la herramienta rmic y las funciones antiguas de la herramienta JavaDoc. Las implementaciones de SocketImpl anteriores a JDK 1.4 tampoco son compatibles.

7. Conclusión

En este artículo, vimos las cinco propuestas de mejora de JDK implementadas por Java 13. También enumeramos algunas otras adiciones y eliminaciones notables.

Como de costumbre, el código fuente está disponible en GitHub.