JavaRush /Blog Java /Random-ES /Lanzamiento de Java 11: nuevas características y capacida...

Lanzamiento de Java 11: nuevas características y capacidades

Publicado en el grupo Random-ES
Anteriormente, las nuevas versiones de Java aparecían raramente y con retrasos. Ahora Oracle mantiene con éxito su ritmo autoestablecido de “nuevo Java cada seis meses”. Hace unos días, estrictamente según lo previsto, finalmente recibimos Java SE 11 y la implementación del JDK (Java Development Kit). Lanzamiento de Java 11: nuevas características y capacidades - 1Como siempre, la nueva versión será compatible con las antiguas y el soporte para Java 11 finalizará no antes de diciembre de 2026.

Nuevas funciones en Java SE 11 (visibles para los desarrolladores)

Recordemos que en Java los cambios se realizan mediante la implementación de la JEP “JDK Enhancement Proposal”. JEP es una propuesta para mejorar OpenJDK y puede aprobarse, retrasarse o rechazarse. Es decir, en esencia, una colección de JEP es una estrategia de desarrollo para OpenJDK. Entre corchetes antes de la nueva “característica” indicaremos el número de la JEP correspondiente. [323] Sintaxis de variable local para parámetros Lambda : sintaxis var para parámetros lambda Java 10 introdujo la palabra clave var, lo que hizo posible no especificar explícitamente el tipo de una variable local. Esto simplificó el código. JEP 323 amplía el uso de esta sintaxis con expresiones lambda. Ejemplo sencillo:
list.stream ()
                 .map ((var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
Como escribe Simon Ritter , un conocido evangelista de Java, un programador experimentado de Java notará que usar var en este caso puede ser innecesario, ya que el código anterior se puede reemplazar con lo siguiente:
list.stream ()
                  .map (s -> s.toLowerCase ())
                  .collect (Collectors.toList ());
¿Por qué entonces apoyar var? Sólo hay un caso especial: cuando desea agregar una anotación a un parámetro lambda. Esto no se puede hacer sin algún tipo involucrado y para evitar tener que usar un tipo explícito, podemos simplificar todo usando var de esta manera:
list.stream ()
                 .map ((@ Notnull var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
[330] Lanzar programas de código fuente de un solo archivo Mejorar el iniciador de Java para iniciar un programa como un solo archivo con código fuente de Java A menudo se critica a Java por su sintaxis detallada y su “ceremonia” de varios pasos para iniciar incluso una aplicación trivial. A veces esto asusta a los novatos. Escribir una aplicación que simplemente imprima "¡ Hola mundo! " ", necesitas escribir una clase con un voidmétodo principal estático público y usar el archivo System.out.println. Habiendo hecho esto, debes compilar el código usando javac . Finalmente, después de esto, puede iniciar la aplicación, que mostrará el saludo desafortunado (por supuesto, el entorno de desarrollo integrado, tanto IDEA como el integrado en JavaRush , realiza esta "magia de inicio de aplicación" por sí solo - nota del editor ). Seamos honestos: en la mayoría de los lenguajes de programación, el script real para ejecutar programas parece mucho más simple. JEP 330 elimina la necesidad de compilar una aplicación de un solo archivo, por lo que ahora, si usa la línea de comando, simplemente escriba
java HelloWorld.java
El iniciador de Java detectará que el archivo contiene código fuente de Java y compilará el código en un archivo de clase antes de ejecutarlo. Puede colocar parámetros después o antes del nombre del archivo del código fuente. Los que se colocan después del nombre se pasan como parámetros cuando se ejecuta la aplicación. Los colocados antes del nombre se pasan como parámetros al iniciador de Java después de compilar el código. Las opciones específicas del compilador (como classpath) también se pasarán a javac para su compilación. Ejemplo. Línea:
java -classpath / home / foo / java Hello.java Bonjour
será equivalente a estas líneas:
javac -classpath / home / foo / java Hello.java
java -classpath / home / foo / java Hello Bonjour
[321] Cliente HTTP (estándar) : se ha estandarizado el soporte de la API del cliente HTTP. JDK 9 introdujo una nueva API para admitir el protocolo del cliente HTTP (JEP 110) . Dado que JDK 9 también introdujo el Java Platform Module System (JPMS) , esta API se incluyó como un módulo incubador (estos son módulos para proporcionar a los desarrolladores nuevas API que aún no se han convertido en estándar en Java SE, mientras que las API "en vivo" se están preparado para su eliminación: los desarrolladores pueden probar nuevas API e intentar proporcionar comentarios). Una vez que se realizan los cambios necesarios (esta API se actualizó en JDK 10), la API puede pasar a formar parte del estándar. Entonces, la API del cliente HTTP ahora está incluida oficialmente en Java SE 11 . Esto presenta un nuevo módulo y paquete para JDK, java.net.http . Los principales tipos nuevos son: HttpClient HttpRequest HttpResponse WebSocket Esta API se puede utilizar de forma sincrónica o asincrónica. En modo asíncrono, se utilizan CompletionFuturesy CompletionStages. [320] Eliminar los módulos Java EE y CORBA Con la introducción del Java Platform Module System (JPMS) en la novena versión de Java, fue posible dividir el archivo monolítico rt.jar en varios módulos. Además, JPMS le permite crear un entorno de ejecución de Java que incluye sólo los módulos que necesita su aplicación, reduciendo considerablemente su tamaño. Con límites de módulo definidos de forma transparente, es mucho más fácil eliminar partes obsoletas de la API de Java: eso es lo que hace JEP 320. El metamódulo java.se.ee incluye seis módulos que no formarán parte del estándar Java SE 11 y no se incluirán. en el JDK:
  • corba
  • transacción
  • activación
  • xml.bind
  • xml.ws
  • xml.ws.anotación
Estos módulos quedaron obsoletos en JDK 9 y no se incluyeron de forma predeterminada en la compilación o ejecución. Esto significa que si intentó compilar o ejecutar una aplicación que utiliza las API de estos módulos en JDK 9 o JDK 10, falló. Si utiliza las API de estos módulos en su código, deberá proporcionarlas como un módulo o biblioteca independiente.

Nuevas API

Una gran cantidad de nuevas API en JDK 11 aparecieron gracias a la inclusión de los módulos HTTP Client y Flight Recorder en el estándar del lenguaje . Para obtener una lista completa de API, consulte la siguiente comparación completa de diferentes versiones del JDK , compilada por Gunnar Morling. Y en esta nota enumeraremos algunos métodos nuevos que no están incluidos en los módulos java.net.http , jdk.jfr y java.security . java.lang.String Posiblemente uno de los cambios más importantes en String en la API JDK 11, hay varios métodos nuevos y útiles.
  • boolean isBlank (): devuelve verdadero si la cadena está vacía o contiene solo espacios, falso en caso contrario.

  • Stream lines(): Devuelve un flujo de líneas extraídas de esta cadena, separadas por terminadores de línea.

  • String repeat (int): Devuelve una cadena cuyo valor es la concatenación de esa cadena repetida int veces.

  • String strip (): Devuelve una cadena con todos los espacios eliminados antes o después del primer carácter que no sea un espacio.

  • String stripLeading (): Devuelve una cadena con todos los espacios hasta el primer carácter que no sea un espacio eliminado.

  • String stripTrainling (): Devuelve una cadena con todos los espacios que aparecen después del último carácter que no es un espacio eliminado.
strip()El método ya hizo algo similar trim (), pero por espacios estos métodos significan cosas diferentes. En este caso, trim()solo se cortan los espacios y strip()también los caracteres especiales, como las tabulaciones. java.lang.StringBuffer java.lang.StringBuilder Ambas clases contienen un nuevo método compareTo ()que acepta StringBuffer/ StringBuildery devuelve int. El método de comparación léxica es similar al nuevo método compareTo() CharSequence. java.io.ByteArrayOutputStream
  • void writeBytes (byte []): escribe todos los bytes del parámetro en el flujo de salida java.io.FileReader
Hay dos nuevos constructores aquí que le permiten especificar Charset. java.io.FileWriter Cuatro nuevos constructores que le permiten especificar Charset. java.io.InputStream
  • io.InputStream nullInputStream (): devuelve InputStream, que no lee ningún byte. ¿Cómo utilizar este método? Puedes pensar en ello como algo así como /dev/null para desechar resultados que no necesitas, o para inyectar entradas que siempre devuelven cero bytes.
java.io.OutputStream
  • io.OutputStream nullOutputStream ()
java.io.Reader
  • io.Reader nullReader ()
java.io.Escritor
  • io.Writer nullWriter ()
java.lang.Carácter
  • String toString (int): Esta es una sobrecarga de un método existente, pero usa int en lugar de char.
java.lang.CharSequence
  • int compare (CharSequence, CharSequence): compara lexicográficamente dos instancias CharSequence. Devuelve un valor negativo, cero o un valor positivo si la primera secuencia es lexicográficamente menor, igual o mayor que la segunda, respectivamente.
java.lang.ref.Referencia
    lang.Object clone (): El evangelista de Java Simon Ritter admite que este método lo confunde. La clase Referenceno implementa una interfaz Cloneabley este método siempre generará una excepción CloneNotSupportedException. Sin embargo, el experto sugiere que este método servirá para algo en el futuro.
java.lang.Runtime java.lang.System No hay métodos nuevos aquí. Solo mencionemos que el método runFinalizersOnExit ()se eliminó de ambas clases, lo que puede causar problemas de compatibilidad. java.lang.Thread No hay métodos adicionales, solo mencionaremos que destroy ()fueron stop (Throwable)eliminados. Sin embargo stop (), que no acepta argumentos, todavía está disponible. Tenga esto en cuenta ya que puede haber problemas de compatibilidad. java.nio.ByteBuffer java.nio.CharBuffer java.nio.DoubleBuffer java.nio.FloatBuffer java.nio.LongBuffer java.nio.ShortBuffer En todas estas clases, los desarrolladores del lenguaje agregaron un método mismatch ()que encuentra y devuelve el índice relativo del primera discrepancia entre este búfer y un búfer determinado. java.nio.channels.SelectionKey
  • int interestOpsAnd (int)

  • int interestOpsOr (int)
java.nio.channels.Selector
  • int select (java.util.function.Consumer, long): Selecciona y ejecuta una acción en las teclas cuyos canales correspondientes están listos para operaciones de E/S. El parámetro largo es un tiempo de espera.

  • int select (java.util.function.Consumer): funciona como el método anterior, pero sin el tiempo de espera.

  • int selectNow (java.util.function.Consumer): funciona como el método anterior, solo que no es bloqueante.

java.nio.file.Archivos
  • String readString (Path): Lee todo el contenido de un archivo en una cadena, decodificando bytes en caracteres usando codificación UTF-8 .

  • String readString (Path, Charset): Funciona como el método anterior, pero decodifica bytes en caracteres usando Charset.

  • Path writeString (Path, CharSequence, java.nio.file. OpenOption []): Si escribe una secuencia de caracteres CharSequenceen un archivo, esos caracteres se codificarán en bytes (usando UTF-8 ).

  • Path writeString (Path, CharSequence, java.nio.file. Charset, OpenOption []): funciona como el método anterior, solo los caracteres se codifican en bytes usando Charset.
java.nio.archivo.Ruta
  • Ruta(Cadena, Cadena[]): Devuelve la Ruta, transformando una cadena de ruta o una secuencia de cadenas que cuando se combinan forman una cadena de ruta.

  • Ruta (net.URI): Devuelve la ruta transformando el URI.
java.util.Colección
  • Object [] toArray (java.util.function.IntFunction): Devuelve una matriz que contiene todos los elementos de esta colección, utilizando la función generadora proporcionada para distribuir la matriz devuelta.
java.util.concurrent.PriorityBlockingQueue java.util.PriorityQueue
  • void forEach (java.util.function.Consumer): Realiza la acción especificada en cada elemento Iterable hasta que se hayan procesado todos los elementos o la acción genere una excepción.

  • boolean removeAll (java.util.Collection): Elimina todos los elementos de esta colección que también están contenidos en la colección especificada (operación opcional).

  • boolean removeIf (java.util.function.Predicate): Elimina todos los elementos de esta colección que satisfacen el predicado dado.

  • boolean retainAll (java.util.Collection): Conserva solo los elementos de esta colección que están contenidos en la colección especificada (operación opcional).
java.util.concurrent.TimeUnit
  • long convert (java.time.Duration): Convierte la duración de tiempo dada a esta unidad.
java.util.función.Predicado
  • Predicate not(Predicate): devuelve un predicado que es la negación del predicado dado.
Por ejemplo, el siguiente código:
lines.stream ()

.filter (s ->! s.isBlank ())
se puede convertir a esto:
lines.stream ()

.filter (Predicate.not (String :: ISBLANK))
y si usamos importación estática, esto es lo que obtenemos:
lines.stream ()
.filter (not(String :: ISBLANK))
java.util.Optional java.util.OptionalInt java.util.OptionalDouble java.util.OptionalLong
  • boolean isEmpty (): Devuelve verdadero si no hay ningún valor , falso en caso contrario .
java.util.regex.Patrón
  • Predicate asMatchPredicate (): El experto en Java Simon Ritter cree que aquí puede haber una auténtica joya API de JDK 11. Este método crea un predicado que comprueba si este patrón coincide con una cadena de entrada determinada.
java.util.zip.Deflactador
  • int deflate (ByteBuffer): comprime los datos de entrada y llena el búfer especificado con datos comprimidos.

  • int deflate (ByteBuffer, int): comprime los datos de entrada y llena el búfer especificado con datos comprimidos. Devuelve la cantidad real de datos comprimidos.

  • void setDictionary (ByteBuffer): configura el diccionario dado para que se comprima en bytes en el búfer dado. Esta es una sobrecarga de un método existente que ahora puede aceptar una ByteBuffermatriz de bytes, en lugar de una.

  • void setInput (ByteBuffer): establece los datos de entrada que se comprimirán. También es una sobrecarga de un método existente.
java.util.zip.Inflador
  • int inflate (ByteBuffer): descomprime bytes en el búfer especificado. Devuelve el número real de bytes sin comprimir.

  • void setDictionary (ByteBuffer): establece el diccionario dado en los bytes del búfer dado. Es una forma sobrecargada de un método existente.

  • void setInput (ByteBuffer): establece los datos de entrada para la descompresión. Una forma sobrecargada de un método existente.
javax.print.attribute.standard.DialogOwner Esta es una nueva clase en JDK 11 y es una clase de atributo utilizada para admitir solicitudes de impresión o personalización de páginas que se mostrarán en la parte superior de todas las ventanas o en una ventana específica. javax.swing.DefaultComboBoxModel javax.swing.DefaultListModel
  • void addAll (Collection): Agrega todos los elementos presentes en la colección.

  • void addAll (int, Collection): Agrega todos los elementos presentes en la colección, comenzando en el índice especificado.
javax.swing.ListSelectionModel
  • int [] getSelectedIndices (): Devuelve una matriz de todos los índices seleccionados en el modelo seleccionado en orden ascendente.

  • int getSelectedItemsCount (): Devuelve el número de elementos seleccionados.
jdk.jshell.EvalException
  • shell.JShellException getCause (): Devuelve el motivo arrojable en el cliente de ejecución presentado por esta EvalException, o nulo si el motivo no existe o es desconocido.

Funciones que no son de desarrollador de Java 11

[181] Control de acceso basado en Nest Java y otros lenguajes admiten clases anidadas a través de clases internas. Para que esto funcione, el compilador debe realizar ciertos trucos. Por ejemplo:
public class Outer {
    private int outerInt;

     class Inner {
       public void printOuterInt() {
         System.out.println("Outer int = " + outerInt);
       }
     }
   }
El compilador modifica esto para producir algo como lo siguiente antes de compilar:
public class Outer {
      private int outerInt;

      public int access$000() {
        return outerInt;
      }

    }


    class Inner$Outer {

      Outer outer;

      public void printOuterInt() {
        System.out.println("Outer int = " + outer.access$000());
      }
    }
Aunque lógicamente la clase interna es parte del mismo código que la clase externa, se compila como una clase separada. Por lo tanto, esta operación requiere un método de unión sintética que debe crear el compilador para proporcionar acceso al campo privado de la clase externa. Este JEP introduce el concepto de nidos, donde dos miembros del mismo nido (externo e interno en nuestro ejemplo) son compañeros de anidación. Se definen dos nuevos atributos para el formato de archivo de clase: NestHost y NestMembers . Estos cambios son útiles para otros lenguajes que admiten clases anidadas y códigos de bytes. Esta función introduce tres nuevos métodos para java.lang.Class : Clase getNestHost () Clase [] getNestMembers () boolean isNestmateOf (Clase) [309] Constantes dinámicas de archivo de clase Este JEP describe una extensión del formato de archivo de clase para admitir el nuevo formulario de grupo persistente CONSTANT_Dynamic. La idea de una constante dinámica parece un oxímoron, pero esencialmente puedes considerarla como un valor final en Java 11. El valor de una constante de agrupación no se establece en el momento de la compilación (a diferencia de otras constantes), sino que utiliza un arranque. Método para determinar el valor en el tiempo de entrega. Por tanto, el valor es dinámico, pero como su valor se establece sólo una vez, también es constante. Esta característica está dirigida principalmente a personas que desarrollan nuevos lenguajes y compiladores que generarán códigos de bytes y archivos de clase como salida para ejecutar en la JVM. [315] Mejorar los intrínsecos de Aarch64 Este JEP fue propuesto por la comunidad de Red Hat. La JVM ahora puede utilizar instrucciones más especializadas disponibles en el conjunto de instrucciones Arm 64. En particular, esto mejora el rendimiento de los métodos sin ()y cos ()la log ()clase java.lang.Math . [318] Epsilon: un recolector de basura sin operación Al igual que con JEP 315 , puede agradecer a Red Hat por la introducción del recolector de basura Epsilon. ¡Epsilon es inusual porque en realidad no recolecta basura! Al crear nuevos objetos, asigna memoria si es necesario, pero no recupera el espacio ocupado por objetos no registrados. " ¿ Cuál es el punto de? ", - usted pregunta. Resulta que esta “recolección de basura” tiene dos usos:
  1. En primer lugar, este recolector de basura está diseñado para garantizar que los nuevos algoritmos de GC se evalúen en términos de su impacto en el rendimiento. La idea es ejecutar una aplicación de muestra con Epsilon y generar un conjunto de métricas. Se habilita el nuevo algoritmo de recolección de basura, se ejecutan las mismas pruebas y luego se comparan los resultados.

  2. Para tareas muy cortas (piense en funciones sin servidor en la nube) en las que puede garantizar que no excederá la memoria asignada al montón. Esto puede mejorar el rendimiento al eliminar la sobrecarga (incluida la recopilación de estadísticas necesarias para decidir si se ejecuta el recopilador) en el código de la aplicación. Si se agota el espacio del montón, la JVM puede estar mal configurada de una de estas tres maneras:
    • Normal se llama OutOfMemoryError.
    • Realizar un reinicio del montón
    • El disco duro JVM falló y es posible que esté realizando otra tarea (como iniciar un depurador).
[328]: Flight Recorder Flight Recorder es un marco de adquisición de datos de bajo nivel para la JVM. Antes de JDK 11, esta era una característica comercial en el binario Oracle JDK. Oracle ahora está eliminando las diferencias funcionales entre Oracle JDK y una compilación de OpenJDK. Esto es lo que hace Flight Recorder :
  • Proporciona una API para producir y consumir datos como eventos.
  • Proporciona un mecanismo de búfer y formato de datos binarios.
  • Permite la personalización y filtrado de eventos.
  • Proporcionar eventos para OS, JVM HotSpot y bibliotecas JDK
Hay dos módulos nuevos aquí: jdk.jfr y jdk.management.jfr . [329] Algoritmos criptográficos ChaCha20 y Poly1305 Este JEP trata sobre la actualización de los cifrados utilizados por el JDK. Este caso implementa los algoritmos de cifrado ChaCha20 y ChaCha20-Poly1305 como se especifica en RFC 7539. ChaCha20 es un cifrado de flujo relativamente nuevo que puede reemplazar al antiguo e inseguro cifrado RC4 . [333] ZGC: Un recolector de basura escalable de baja latencia Un recolector de basura experimental escalable de baja latencia. Diseñado para usarse con aplicaciones que requieren un montón grande (de varios gigabytes) y baja latencia. Utiliza un montón de generación única y realiza la mayor parte (pero no todo) del trabajo de recolección de basura al mismo tiempo que la aplicación. [332] Seguridad de la capa de transporte (TLS) 1.3 TLS 1.3 (RFC 8446) es un parche importante para el protocolo de seguridad de la capa de transporte TLS que proporciona importantes mejoras de seguridad y rendimiento con respecto a versiones anteriores. El JDK ahora admite esta versión del protocolo. El material está basado en un artículo de Simon Ritter y documentación oficial .
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION