JavaRush /Blog Java /Random-ES /Java 14: ¿qué hay de nuevo?

Java 14: ¿qué hay de nuevo?

Publicado en el grupo Random-ES
Los problemas del mundo son los problemas del mundo y el nuevo Java va según lo previsto. Es decir, exactamente una vez cada seis meses. La versión de lanzamiento de Java 14 se lanzó el 17 de marzo e introdujo varias innovaciones interesantes en el lenguaje dirigidas a los desarrolladores. Java 14: ¿qué hay de nuevo?  - 1Entre ellos se encuentran soporte experimental para la palabra clave record , soporte para coincidencia de patrones en el operador " instanceof ", NullPointerExceptions más fáciles de usar , "vista previa" ampliada de bloques de texto , un interruptor predeterminado actualizado y mucho más. Permítanos recordarle que todas las innovaciones en Java comienzan con propuestas de extensión ( JEP, Java Enhancement Proposals ). Los desarrolladores proponen cambios, son revisados ​​por los padres "oficiales" de Java y luego algunos de esos cambios son aceptados, después de lo cual pasan a formar parte del JDK. Y ahora, todo en orden.

JEP 359: Registros

Los registros, también conocidos como Registros, están disponibles para JDK 14 en modo de vista previa, y esto es algo completamente nuevo para Java. De hecho, tenemos ante nosotros un nuevo tipo que se desarrolló durante el proyecto Valhalla . Los registros son similares a las enumeraciones y le permiten simplificar su código. Esencialmente, reemplazan clases que tienen estado pero no comportamiento. En pocas palabras, hay campos, no métodos. En el caso de las clases, a veces tenemos que escribir mucho código repetitivo que no siempre es necesario: constructores, descriptores de acceso, iguales(), hashCode(), toString(), etc. Para evitar este código repetitivo, Java planea para utilizar el registro. Aquí está la versión clásica:

final class Triangle {
 	public final int x;
public final int y;
public final int z;
 
    public Triangle(int x, int y, int z) {
         this.x = x;
         this.y = y;
    this.z = z;
    }
    // equals, hashCode, toString
Pasemos a Java 14 y usemos el registro:

public record Triangle(int x, int y, int z){}
Eso es todo. Tenga en cuenta que las grabaciones existen actualmente en forma de vista previa, por lo que para probarlas en la práctica debe descargar jdk14 e ingresar el comando:

javac —enable-preview —release 14 Triangle.java
Los récords son clases, aunque con limitaciones. No pueden ampliar otras clases ni declarar campos (excepto el final privado que corresponde a los componentes de la declaración estatal). Los registros son implícitamente definitivos y no pueden ser abstractos. Los registros se diferencian de las clases normales en que no pueden separar su API de su representación. Pero la pérdida de libertad se compensa con una mayor precisión. Los componentes del registro también son implícitamente definitivos.

JEP 305: Coincidencia de patrones por ejemplo de (Vista previa)

La función de coincidencia de patrones , introducida en Java 14 en la versión preliminar, está diseñada para combinar la verificación del tipo de un objeto y su conversión en el operador de instancia . En otras palabras, antes de Java 14 habría existido, por ejemplo, el siguiente código:

Object object = Violin;
 
if (object instanceof Instrument) {
    Instrument instrument = (Instrument) object;
    System.out.println(instrument.getMaster());
}
Como puede ver, debemos convertir el objeto a la clase cuyos métodos queremos usar. Ahora Java 14 y la función de coincidencia de patrones conectada le permiten reducir el código a lo siguiente:

Object object = Violin;
 
if (object instanceof Instrument instrument){
    System.out.println(instrument.getMaster());
}

JEP 343: Herramienta de embalaje (Incubadora)

JDK 8 tenía una herramienta javapackager diseñada para JavaFX. Sin embargo, tras la separación de JavaFX de Java con el lanzamiento de JDK 11, el popular javapackager ya no estaba disponible. Javapackager era una herramienta de empaquetado. Permitió que las aplicaciones Java se empaquetaran de tal manera que pudieran instalarse como todos los demás programas "normales". Por ejemplo, cree archivos exe para usuarios de Windows e inicie una aplicación Java como un humano, con un doble clic. Por supuesto, existe una gran falta de una herramienta de este tipo, por lo que JEP 343 introdujo una nueva herramienta, jpackage , que empaqueta una aplicación Java en un paquete específico de la plataforma que contiene todas las dependencias necesarias. Formatos de paquetes admitidos para una plataforma específica:
  • Linux: deb y rpm
  • macOS: paquete y dmg
  • Windows: MSI y EXE

JEP 345: Asignación de memoria compatible con NUMA para G1

JEP 345 sirve únicamente para implementar el soporte NUMA (acceso a memoria no uniforme). Se trata de arquitecturas heterogéneas de acceso a la memoria, una forma de configurar un clúster de microprocesadores en un sistema multiprocesador en el que la memoria se puede distribuir localmente: cada núcleo del procesador obtiene una pequeña cantidad de memoria local, mientras que otros núcleos tienen acceso a ella. JEP 345 planea equipar al recolector de basura G1 con la capacidad de aprovechar dichas arquitecturas. Entre otras cosas, este enfoque ayuda a mejorar el rendimiento en máquinas muy potentes.

JEP 349: Transmisión de eventos JFR

Java Flight Recorder (JFR) ahora forma parte de OpenJDK y, por lo tanto, está disponible gratuitamente. JDK 14 agrega una API para el seguimiento sobre la marcha de eventos JFR (JDK Flight Recorder), en particular para organizar el seguimiento continuo de aplicaciones activas e inactivas. Se registran los mismos eventos que para la opción no streaming, con un coste general inferior al 1%. De esta manera los eventos se transmitirán al mismo tiempo que la opción sin transmisión. Sin embargo, JEP 349 no debe permitir devoluciones de llamada sincrónicas para el consumidor correspondiente. Incluso los datos de registros almacenados en la memoria intermedia no deberían ser accesibles. Técnicamente, el paquete jdk.jfr.consumer en el módulo jdk.jfr se ampliará con funcionalidad para acceso asincrónico a eventos.

JEP 352: Búfers de bytes asignados no volátiles

Como sabemos, la API de archivos Java NIO (New IO) existe desde JDK 1.4 y luego se introdujo una nueva mejora llamada Path. Path es una interfaz que reemplaza a la clase java.io.File como representación de un archivo o directorio cuando trabajamos en Java NIO. JEP 352 extiende MappedByteBuffer para cargar una parte de los datos del archivo en la memoria no volátil (NVM). Esta memoria de computadora, en la que los datos no se perderán incluso si se apaga la alimentación (a menudo llamada memoria persistente), se utiliza para almacenar datos permanentemente. Esta propuesta de mejora de Java proporciona un nuevo módulo y clase para la API JDK: el módulo jdk.nio.mapmode, que ofrece nuevos modos (READ_ONLY_SYNC, WRITE_ONLY_SYNC) para crear buffers de bytes mapeados (MappedByteBuffer) que hacen referencia a NVM.

JEP 358: excepciones útiles de puntero nulo

NullPointerExceptions ahora será más amigable para los programadores. En el sentido de que la descripción de la excepción será mucho más informativa que antes. Esto se debe a que a la JVM se le ha enseñado a analizar con mayor precisión las instrucciones de código de bytes del programa y puede indicar qué variable conduce a un valor cero. Digamos que tenemos el código:

a.getMessage().getUserInfo().getName()
En cualquiera de las últimas versiones de Java obtendremos el registro de errores habitual, que no responde a la pregunta de quién es exactamente nulo:

Exception in thread "main" java.lang.NullPointerException
	at Main.main(Main.java:12)
Y esto es lo que Java 14 le ofrecerá si decide probar esta función de vista previa:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "UserInfo().getName()" because the return value of "Message().getUserInfo()" is null
	at Main.main(Main.java:12)
Esta cadena es mucho más comprensible y permite abordar el error mucho más rápido.

JEP 361: Cambiar expresiones (estándar)

El operador Switch actualizado estaba disponible en Java 12 y 13 anteriores, pero solo como función de vista previa, es decir, no estaba habilitado de forma predeterminada. Ahora en JDK 14 todo funciona desde el primer momento. Java 14 introduce una nueva forma simplificada del bloque de interruptor con etiquetas caso L ->.... La nueva forma simplifica el código en algunos casos. Aquí hay un par de ejemplos. Digamos que tenemos una enumeración que describe los días de la semana. Podemos escribir código clásico (anterior a Java 14):

switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        break;
    case TUESDAY:
        System.out.println(7);
        break;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        break;
    case WEDNESDAY:
        System.out.println(9);
        break;
}
Y aquí hay una opción que usa Java 14:

switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}
También puedes escribir bloques de varias líneas y devolver un valor con la nueva palabra clave de rendimiento:

int result = switch (s) {
    case "Working from Home" -> 1;
    case "Working from Office" -> 2;
    default    -> {
        System.out.println("Neither Home nor Office… Cafe? Car? Park?...");
        yield 0;
    }
};
Hay algunas cosas más importantes a tener en cuenta al utilizar los nuevos interruptores . En particular, hay que recordar que las opciones deben ser exhaustivas. Es decir, para todos los valores posibles debe haber una etiqueta de interruptor correspondiente. Dado que rendimiento ahora es una palabra clave, una clase llamada rendimiento es posible en Java 14. En general, si desea aprender a utilizar los modificadores actualizados, vaya a JEP 361 y estudie. Hay mucha información interesante allí.

JEP 362: desaprobar los puertos Solaris y SPARC

Es poco probable que muchos de nuestros lectores recuerden el sistema operativo Solaris . Este sistema operativo basado en UNIX, creado por los padres de Java, Sun Microsystems, se utilizó principalmente para servidores con arquitectura SPARC... ¿Demasiadas palabras desconocidas por centímetro cuadrado? No es gran cosa: JEP 362 finaliza el soporte para las plataformas Solaris/SPARC, Solaris/x64 y Linux/SPARC. Es decir, sus puertos ahora están en desuso y, en el futuro, lo más probable es que se eliminen de OpenJDK. Sin embargo, las versiones anteriores de Java (anteriores a JDK 14) con respecto a los puertos Solaris/SPARC, Solaris/x64 y Linux/SPARC deberían funcionar sin modificaciones. Si es un aficionado a la historia y está interesado en tecnologías de un pasado no muy lejano, vaya a Wikipedia y lea sobre la arquitectura SPARС .

JEP 363: Eliminar el recolector de basura de barrido concurrente de marcas (CMS)

El recolector de basura CMS (Concurrent Mark Sweep) está destinado a ser eliminado porque hace dos años se marcó como obsoleto y no se le dio mantenimiento. Sin embargo, los usuarios de versiones anteriores de Java que utilizan CMS GC pueden exhalar: el propósito de este JEP no es eliminar el generador de versiones anteriores de JDK. Además, la combinación de los algoritmos de recolección de basura ParallelScavenge y SerialOld (que se ejecutan con las opciones "-XX:+UseParallelGC -XX:-UseParallelOldGC") ha quedado obsoleta.

JEP 364: ZGC en macOS y JEP 365: ZGC en Windows

Hay un recolector de basura interesante llamado Z Garbage Collector (ZGC) . Funciona en modo pasivo e intenta minimizar los retrasos debidos a la recolección de basura: el tiempo de parada cuando se usa ZGC no supera los 10 ms. Puede funcionar con montones pequeños y gigantes (aquellos que ocupan muchos terabytes). JEP 364 y ​​JEP 365 son prácticamente gemelos. JEP 364 lleva Z Garbage Collector a MacOS. Parte del JEP también describe la funcionalidad del recopilador para liberar memoria del dispositivo no utilizada, como se especifica en JEP 351 , esto ha estado sucediendo desde Java 13. La implementación de ZGC en macOS tiene dos partes:
  • Soporte de memoria de mapeo múltiple en macOS
  • Soporte ZGC para reserva de memoria continua
JEP 365 proporciona soporte para ZGC ya en Windows y también en modo experimental. Es el siguiente:
  • Soporte de memoria de mapeo múltiple
  • Soporte para mapeo de memoria basado en el archivo de página en un espacio de direcciones reservado
  • Soporte para mapear y desasignar partes arbitrarias del montón
  • Soporte para confirmar y cancelar partes arbitrarias del montón

JEP 366: Desaprobar la combinación ParallelScavenge + SerialOld GC

Este JEP desaprueba la combinación de algoritmos de recolección de basura Parallel Scavenge y Serial Old. Esta combinación debía habilitarse manualmente usando los parámetros de la línea de comando -XX: + UseParallelGC -XX: -UseParallelOldGC. Los autores creen que la combinación es muy específica, pero también requiere un importante esfuerzo de mantenimiento. Así que ahora la opción -XX: UseParallelOldGC está obsoleta y aparecerá una advertencia si se usa.

JEP 367: Eliminar las herramientas y API Pack200

Pack200 es un formato de archivo optimizado para almacenar archivos de clase Java compilados. Esta herramienta se ha marcado como obsoleta desde Java 11. Ahora se ha anunciado oficialmente la eliminación de las herramientas API pack200, unpack200 y Pack200 del paquete java.util.jar . Esta tecnología se introdujo en Java 5 como una forma de lidiar con un ancho de banda muy limitado (módems, da miedo decirlo y recordarlo, 56k) y espacio de almacenamiento insuficiente en los discos duros. Hace algún tiempo, Java 9 introdujo nuevos esquemas de compresión. Se anima a los desarrolladores a utilizar jlink .

JEP 368: Bloques de texto (segunda vista previa)

Los bloques de texto aparecieron por primera vez en Java 13. Son literales de cadena multilínea que evitan la necesidad de la mayoría de secuencias de escape, formatean automáticamente la cadena y también permiten al desarrollador formatear la cadena si es necesario. Esta útil característica ahora está disponible en Java 14 (segunda vista previa). El objetivo principal de los bloques de texto es mejorar el manejo de literales de varias líneas confusos. Esto simplifica enormemente la lectura y escritura de consultas SQL, código HTML y XML y JSON. Ejemplo de HTML sin bloques de texto:

String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, JavaRush Student</p>\n" +
              "    </body>\n" +
              "</html>\n";
Cómo representar lo mismo con bloques de texto:

String html = """
              <html>
                  <body>
                      <p>Hello, JavaRush Student</p>
                  </body>
              </html>
              """;
El delimitador de apertura es una secuencia de tres caracteres de comillas dobles ("" "), seguidos de cero o más espacios, y luego un delimitador de línea. El contenido comienza en el primer carácter después del delimitador de línea del delimitador de apertura. El delimitador de cierre es Se eligió una secuencia de tres caracteres de comillas dobles " _ ) para que los caracteres pudieran mostrarse sin escapes y también distinguir visualmente un bloque de texto de una cadena literal. A principios de 2019, JEP 355 propuso bloques de texto como continuación de JEP 326 (literales de cadena sin formato), pero fueron retirados. Más tarde ese año, JDK 13 introdujo la función de vista previa de bloques de texto y ahora Java 14 ha agregado dos nuevas secuencias de escape. Este es un terminador de línea, denotado \, y el segundo es para espacio simple, denotado /s. Un ejemplo de uso de nuevas líneas sin bloques de texto:

String literal = "This is major Tom to Ground Control " +
"I am stepping through the door... " +
"Wait… What???";
Y ahora con la secuencia de escape \<line-terminator>:

String text = """
                This is major Tom to Ground Control \
                I am stepping through the door... \
                WaitWhat???\
                """;
La secuencia de escape \s se utiliza para tener en cuenta los espacios en blanco finales, que el compilador ignora de forma predeterminada. Conserva todos los espacios en blanco que lo preceden. Ejemplo:

String text1 = """
               line1
               line2 \s
               line3
               """;
  
String text2 = "line1\nline2 \nline3\n";
text1y text2son identicos.

JEP 370: API de acceso a memoria externa (incubadora)

Muchas bibliotecas y programas Java populares tienen acceso a la memoria externa. Por ejemplo, Ignite, MapDB, Memcached y Netty ByteBuf API. Al hacerlo, pueden evitar el costo y la imprevisibilidad asociados con la recolección de basura (especialmente cuando sirven cachés grandes), compartir memoria entre múltiples procesos y serializar y deserializar contenidos de la memoria mediante el mapeo de archivos en la memoria (por ejemplo, usando mmap). Sin embargo, la API de Java todavía no tiene una solución adecuada para acceder a la memoria externa. JDK 14 incluye una vista previa de la API Foreign-Memory Access , que permite a las aplicaciones Java acceder de forma segura y eficiente a regiones de memoria fuera del montón de JVM utilizando las nuevas abstracciones MemorySegment, MemoryAddress y MemoryLayout.

conclusiones

¿Entonces, qué piensas? En comparación con Java 13, el nuevo Java 14 ofrece muchas más mejoras importantes en una variedad de áreas. Lo más probable es que lo más importante para los desarrolladores sea el interruptor actualizado, las excepciones extendidas NullPointerExceptions y los registros. ¿O no?... No olvides probar las nuevas funciones de Java 14, es muy útil incluso para principiantes. ¡Buena suerte con sus estudios!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION