JDK 13 introduce 5
nuove JEP (Java Enhancement Proposal): 2, blocchi di testo ed
evoluzione del costrutto switch
, riguardano la sintassi del linguaggio
mentre Dynamic CDS Archive, ZGC uncommit unused memory e
Reimplement the legacy Socket API, si concentrano su aspetti legati
alla virtual machine e API.
Text Blocks
Con Java si è sempre sofferto un pò per via della modalità di
definizione delle stringhe. Una stringa inizia con un double-quote e
finisce con un altro double-quote, tutto il contenuto racchiuso non
può essere sparso su più linee a meno di non ricorrere al concatenamento (+) per le stringhe e al carattere speciale di
newline. Prima di Java 13 avremmo infatti scritto qualcosa del tipo:
String html ="<html>\n" +
"<body>\n" +
"</body>\n" +
"</html>\n";
String json ="{\n" +
"\"name\":\"Mario\",\n" +
"\"cognome\":\"Rossi\"\n" +
"}\n";
per rappresentare un blocco di testo HTML o JSON.
Notiamo come effettivamente la difficoltà in scrittura e lettura sia
evidente. Lo stesso codice in Java 13, attraverso l'utilizzo dei
blocchi, può essere scritto come segue:
String html = """
<html>
<body>
</body>
</html>
""";
String json = """
{
"name":"Mario",
"cognome":Rossi"
}
""";
Un blocco inizia e finisce con un triple double-quote, quanto inserito al suo interno è interpretato come contenuto
testuale, incluse le newline. Il risultato sarà un normale
java.lang.String object
con nessuna differenza a livello di codice
compilato.
Un aspetto importante da notare è che in base alla
definizione di blocco non è possibile costruire un blocco di testo
contenuto su una singola riga. Un'istruzione del tipo:
String html = """<html><body></body></html>""";
fornirebbe un errore di compilazione.
Switch Expressions
Questo enhancement riguarda la modalità con cui è possibile
restituire un valore attraverso l'utilizzo del costrutto switch
.
In Java 13 occorre
utilizzare il nuovo operatore yield
:
private String isMagicNumber(int number) {
return switch (number) {
case 1:
yield "one is not the magic number";
case 2:
yield "two is not the magic number";
case 3:
yield "three is the magic number";
default:
yield "to far to the magic number";
};
}
Dynamic CDS Archives
Questo JEP migliora l'Application Class-Data Sharing introdotto
con la versione 10 di Java al fine di semplificare il processo di
creazione di archivi CDS (Class Data Sharing). L'idea alla base del
Class Data Sharing è di migliorare la velocità di avvio di
applicazioni Java creando archivi una sola volta per riutilizzarli
successivamente.
In questo modo la JVM non dovrà di ricreare lo
stesso archivio più volte. Per utilizzare questa nuova funzionalità è
sufficiente creare e lanciare l'applicativo utilizzando i parametri
-XX:ArchiveClassesAtExit
e -XX:SharedArchiveFile
:
java -XX:ArchiveClassesAtExit=myapp.jsa -cp myapp.jar MyApp
java -XX:SharedArchiveFile=myapp.jsa -cp myapp.jar MyApp
Uncommit Unused Memory
ZGC è un garbage collector sperimentale introdotto con la
versione 11 di Java. La sua implementazione non consente il ritorno al
sistema operativo di pagine di memoria non più utilizzate.
Per
ambienti come i container, dove le risorse sono condivise tra diversi
servizi, questa caratteristica limita scalabilità ed efficienza del
sistema. L'heap dello ZGC consiste in un insieme di regioni chiamate
ZPage. Una ZPage rimasta vuota durante un ciclo del garbage
collector viene restituita alla ZPageCache.
Le ZPage
sono organizzate attraverso un ordinamento del tipo LEAST RECENTLY
. Con le JDK 13, lo ZGC restituirà al sistema operativo pagine
USED
identificate come non più utilizzate da un determinato periodo di
tempo. Questa variazione del comportamento originale, metterà a
disposizione di altri processi del sistema operativo pagine inutilizzate dalla JVM.
Legacy Socket API
Le implementazioni delle classi java.net.Socket
e
java.net.ServerSocket
sono rimaste immutate dalla prima versione di Java. Le
tecniche utilizzate, come ad esempio stack di Thread e IO buffer, le
rendono non flessibili e difficili da manutenere.
Le JDK 13 forniscono
una nuova implementazione attraverso la classe NioSocketImpl
. Questa classe non
richiede più codice nativo semplificando cosi la portabilità verso
diverse piattaforme. Nel meccanismo di buffer cache
sono stati rimossi gli stack di Thread e ci si affida ai lock di
java.util.concurrent
invece di utilizzare metodi sincronizzati.
Viene in ogni caso mantenuta la retrocompatibilità, se qualcosa non
dovesse funzionare correttamente è possibile tornare alla
vecchia implementazione.