Ya nos hemos acostumbrado al hecho de que aparece una nueva versión de JDK cada seis meses. Hasta ahora, este enfoque se ha justificado, y las preocupaciones de algunos desarrolladores de que no estarán al día con las actualizaciones han sido en vano: hay pocos cambios semestrales y no son tan globales como antes. Bueno, es posible que los programadores novatos no noten la innovación en absoluto. Sin embargo, es mejor para los futuros desarrolladores de software mantenerse al tanto de las innovaciones. En este artículo, describiremos tradicionalmente las propuestas de extensión aceptadas (JEP). Java 13 incluye sólo cinco JEP y 76 nuevos elementos centrales de la biblioteca (de los cuales casi la mitad son simples adiciones al paquete java.io).
JEP 355 : Bloques de texto (vista previa)
Comencemos cambiando la sintaxis del idioma. Los más importantes son los bloques de texto. Le permiten evitar caracteres de escape y saber cómo formatear cadenas. Quizás recuerde que JDK 12 no incluía la característica esperada de Literales de cadena sin formato (JEP 326) para trabajar con literales de cadena. En Java 13, fue reemplazado por JEP 355 con sus bloques de texto. Probablemente recuerdes que en Java, una cadena está entre comillas dobles. Esto es bueno, pero el problema es que una línea no puede ocupar más de una línea del archivo fuente (para evitar confusión con una línea de Java, aquí llamaremos “línea” a una línea de archivo). Bueno, vamos a usar, por ejemplo, el símbolo\n
si se requiere una ruptura o una concatenación de expresiones multilínea. ¡No sale muy bien! Los literales de texto con fragmentos HTML, XML, SQL o JSON incrustados son especialmente engorrosos. Todo este escape, concatenación y edición manual hace que el código sea incómodo de escribir y difícil de leer. Los bloques de texto intentan resolver este problema. Comienzan eh... con comillas dobles triples y terminan con ellas (lo sé, no suena muy bien). Todo lo que está entre comillas se interpreta como parte de la línea, incluidas las nuevas líneas. Los bloques de texto se pueden usar exactamente igual que los literales de texto estándar, y Java compilará el código de la misma manera. Las comillas de apertura deben ir seguidas de un delimitador de línea; Los bloques de texto no se pueden usar en una línea, por lo que el código
String smallBlock = """Only one line""";
dará lugar a los siguientes errores:
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block""";
^
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block""";
^
Ahora se puede escribir un fragmento HTML simple así:
String htmlBlock = """
<html>
<body>
<p>CodeGym Web page</p>
</body>
<html>
""";
Mencionemos algunas sutilezas que es mejor tener en cuenta al utilizar bloques de texto. La ubicación de las comillas finales resulta importante: determina cómo se manejan los espacios en blanco ocasionales. En el ejemplo anterior, las comillas finales están alineadas con la sangría del texto HTML. En este caso, el compilador eliminará los espacios de sangría y, como resultado, obtendremos una línea como esta:
<html>
<body>
<p>My web page</p>
</body>
</html>
Nota:dicha línea contendrá una nueva línea al final de la línea. Si no es necesario, las comillas de cierre “”” se pueden colocar directamente después de la etiqueta </html>. Si acercamos las comillas de cierre al margen izquierdo, esto cambiará la cantidad de sangría eliminada. Si los moviéramos dos espacios hacia la izquierda, agregaríamos dos espacios para sangría a cada línea. Moverse hacia el borde izquierdo hará que se conserve todo el relleno. Mover las comillas más hacia la derecha no tendrá ningún efecto y no agregará más sangría. Los bloques de texto se incluyeron en JDK 13 como función de vista previa. Esto significa que aún no están incluidos en la especificación del lenguaje Java correspondiente. Es decir, no está claro si esta característica se convertirá en una parte permanente del idioma o si será solo una invitada aquí. Actualmente, los desarrolladores pueden probar la función y dar su opinión al respecto. El destino de los bloques de texto dependerá de ello: la función se puede mejorar y, si no te gusta, se puede eliminar por completo. Si desea probar bloques de texto en la práctica, recuerde que las funciones de vista previa deben incluirse explícitamente para poder compilar y ejecutar. Compilacion:
javac --enable-preview --release 13 TextBlock.java
Para ejecutar la aplicación, debe habilitar las funciones de vista previa:
java --enable-preview TextBlock
La clase String
tiene tres nuevos métodos que complementan este cambio de lenguaje:
formatted()
: formatea una cadena utilizando la propia cadena como cadena de formato. Equivalente a un desafíoformat(this, args)
stripIndent()
: Elimina espacios aleatorios de una cadena. Esto es útil si está leyendo cadenas de varias líneas y desea aplicar la misma exclusión de espacios en blanco que lo haría con una declaración explícita.translateEscapes()
: Devuelve una cadena con secuencias de escape (como\ r
), traducidas al valor Unicode apropiado.
@PreviewFeature
ayudaría en tales situaciones, pero aún no está incluida en el JDK (aunque con un alto grado de probabilidad aparecerá en JDK 14).
JEP 354 : Cambiar expresión (vista previa)
Java 12 introdujo una propuesta para una nueva forma de escribir expresiones con una declaración de cambio: JEP 325 . Resultó ser la primera función de vista previa y su destino demuestra que enviar propuestas a los usuarios es una gran idea. Antes de JDK 12,switch
solo podía usarse como una declaración que realiza una acción pero no devuelve un resultado. Pero en Java 12 permitía usarlo switch
como una expresión que devuelve un resultado que se puede asignar a una variable. Hubo otros cambios en la sintaxis de las declaraciones de casos dentro de switch
. Veamos un ejemplo de JEP para entender cómo funciona.
int numberOfLetters;
switch(dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numberOfLetter = 6;
break;
case TUESDAY
numberOfLetter = 7;
break;
case THURSDAY
case SATURDAY
numberOfLetter = 8;
break;
case WEDNESDAY
numberOfLetter = 9;
break;
default:
throw new IllegalStateException("Huh?: " + day);
}
En este ejemplo, usamos value dayOfWeek
para asignar el valor a numberOfLetters
. Debido a las peculiaridades del trabajo del operador switch
, este código no es el más bonito y es fácil cometer errores. Primero, si olvidamos aplicar una declaración break
a cada grupo de etiquetas de casos, pasaremos de forma predeterminada al siguiente grupo de etiquetas de casos. Esto puede provocar errores difíciles de encontrar. En segundo lugar, debemos definir cada grupo de etiquetas de casos. Si lo olvidamos, por supuesto, obtendremos un error del compilador; sin embargo, esta opción no es la ideal. Nuestro código también es bastante detallado porque cada valor dayOfWeek
debe tener su propia etiqueta de caso. Usando la nueva sintaxis, obtenemos un código mucho más limpio y menos propenso a errores:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
default -> throw new IllegalStateException("Huh?: " + day);
};
Ahora solo necesitamos realizar la asignación una vez (a partir del switch
valor de retorno de la expresión) y podemos usar una lista separada por comas para las etiquetas de los casos. Y, al no utilizar el operador break
, eliminamos los problemas asociados al mismo. La sintaxis de expresión switch
nos permite usar una sintaxis de estilo antiguo, por lo que en JDK 12 podemos escribirla así:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
break 6;
case TUESDAY
break 7;
case THURSDAY
case SATURDAY
break 8;
case WEDNESDAY
break 9;
default:
throw new IllegalStateException("Huh?: " + day);
};
Según la comunidad Java, utilizar la sobrecarga break
para especificar un valor de retorno puede resultar confuso. El lenguaje Java también le permite usar break
(y continue
) con una etiqueta como el operador de salto incondicional goto
. JEP 354 cambió este uso break
, por lo que en Java 13 nuestro código cambia ligeramente:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
yield 6;
case TUESDAY
yield 7;
case THURSDAY
case SATURDAY
yield 8;
case WEDNESDAY
yield 9;
default:
throw new IllegalStateException("Huh?: " + day);
};
Los siguientes tres JEP están asociados con la máquina virtual Java.
Archivo CDS dinámico JEP 350
Esta extensión le permite archivar clases dinámicamente al final de la ejecución de una aplicación Java. CDS o Class Data Sharing le permite empaquetar todas las clases iniciadas al inicio en un archivo especialclass data sharing
, utilizando la lista de estas mismas clases de forma predeterminada. Esto conduce a una aceleración significativa en el inicio de aplicaciones y al ahorro de RAM. Anteriormente, usar AppCDS era un proceso de varios pasos que implicaba crear una lista de clases relevantes y usar esa lista para crear un archivo que se usaría para ejecuciones posteriores. Ahora todo lo que se requiere es iniciar la aplicación con el indicador -XX: ArchiveClassesAtExit
que indica la ubicación donde se escribirá el archivo. Con este enfoque, las clases se empaquetan automáticamente en un archivo después de que la aplicación se detiene normalmente.
JEP 351 ZGC : no confirmar la memoria no utilizada
Hace un año, JDK 11 presentó ZGC, un recolector de basura experimental, escalable y de baja latencia. Al principio, ZGC se comportó de manera bastante extraña: no permitía devolver la memoria al sistema operativo, incluso si ya no era necesaria. Para algunos entornos, como los contenedores, donde varios servicios utilizan recursos al mismo tiempo, esto puede limitar la escalabilidad y eficiencia del sistema. El montón ZGC consta de las denominadas ZPages. Cuando las ZPages se borran durante el ciclo de recolección de basura, se devuelven a ZPageCache. Las ZPages en este caché están ordenadas según la fecha de uso. En Java 13, ZGC devolverá al sistema operativo las páginas que se hayan identificado como no utilizadas durante mucho tiempo. De esta forma se pueden reutilizar para otros procesos.JEP 353 Reimplementar la API de socket heredada
Ambas implementaciones de API siguenjava.net.Socket
siendo java.net.ServerSocket
JDK 1.0. En este y en todos los JDK posteriores, la implementación de estas API utiliza varias técnicas (como el uso de la pila de subprocesos como un búfer de E/S) que las hacen inflexibles y difíciles de mantener. Para resolver este problema, se proporcionó una nueva implementación en JDK 13 NioSocketImpl
. Ya no requiere código nativo, lo que facilita la migración a diferentes plataformas. Esta clase también utiliza el mecanismo de caché del búfer existente (evitando el uso de la pila de subprocesos para este propósito) y java.util.concurrent
métodos de bloqueo en lugar de sincronizados. Esto simplificará la integración con fibras de Project Loom .
Nuevas API
Mencionamos anteriormente que Java 13 incluye 76 API nuevas en las bibliotecas de clases base. Cubren las siguientes áreas:- Actualizaciones de soporte Unicode.
- Tres nuevos métodos
String
para admitir bloques de texto (consulte la descripción de JEP 255 más arriba). - Las clases
java.nio
ahora tienen valores absolutos (a diferencia de relativos)get
yestablecer métodos. Ellos, al igual que la clase abstracta base Buffer
, incluyen un métodoslice()
para recuperar parte del búfer. - El método
force()
de claseMappedByteBuffer
fuerza que se escriba una sección del búfer en su almacenamiento de respaldo. nio.FileSystem
Agrega tres nuevas formas sobrecargadasnewFileSystem()
para acceder al contenido de un archivo como un sistema de archivos.- Ha
javax.annotation.processing.ProcessingEnvironment
aparecido un nuevo método interesante.isPreviewEnabled()
. Le indicará si las funciones de vista previa están habilitadas. Esto es interesante porque la anotación mencionada anteriormente@PreviewFeature
no estará disponible hasta que se lance JDK 14. DocumentBuilderFactory
ySAXParserFactory
obtengajavax.xml.parsers
tres nuevos métodos para crear instancias con reconocimiento de espacios de nombres.
GO TO FULL VERSION