Nuove funzionalità di Java 13

1. Panoramica

Settembre 2019 ha visto il rilascio di JDK 13, secondo la nuova cadenza di rilascio di Java di sei mesi . In questo articolo daremo uno sguardo alle nuove funzionalità e ai miglioramenti introdotti in questa versione.

2. Anteprima delle funzionalità per sviluppatori

Java 13 ha introdotto due nuove funzionalità del linguaggio, anche se in modalità anteprima . Ciò implica che queste funzionalità sono completamente implementate per essere valutate dagli sviluppatori, ma non sono pronte per la produzione. Inoltre, possono essere rimossi o resi permanenti nelle versioni future in base al feedback.

È necessario specificare –enable-preview come flag della riga di comando per utilizzare le funzionalità di anteprima . Vediamoli in profondità.

2.1. Cambia espressioni (JEP 354)

Inizialmente abbiamo visto le espressioni switch in JDK 12. Le espressioni switch di Java 13 si basano sulla versione precedente aggiungendo una nuova istruzione yield .

Utilizzando yield , ora possiamo restituire efficacemente i valori da un'espressione switch :

@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); }

Come possiamo vedere, ora è facile implementare il modello di strategia utilizzando il nuovo interruttore.

2.2. Blocchi di testo (JEP 355)

La seconda funzione di anteprima sono i blocchi di testo per stringhe multilinea come JSON incorporato, XML, HTML, ecc.

In precedenza, per incorporare JSON nel nostro codice, lo dichiareremmo come una stringa letterale:

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

Ora scriviamo lo stesso JSON usando i blocchi di testo String :

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

Come è evidente, non è necessario eseguire l'escape dei doppi apici o aggiungere un ritorno a capo. Utilizzando blocchi di testo, il JSON incorporato è molto più semplice da scrivere e più facile da leggere e mantenere.

Inoltre, sono disponibili tutte le funzioni String :

@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); } 

Inoltre, java.lang.String ora ha tre nuovi metodi per manipolare i blocchi di testo:

  • stripIndent () - imita il compilatore per rimuovere lo spazio bianco incidentale
  • translateEscapes () - traduce sequenze di escape come "\\ t" in "\ t"
  • formatted () - funziona come String :: format, ma per i blocchi di testo

Diamo una rapida occhiata a un esempio String :: formatted :

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

Poiché i blocchi di testo sono una funzionalità di anteprima e possono essere rimossi in una versione futura, questi nuovi metodi sono contrassegnati per la deprecazione.

3. Archivi CDS dinamici (JEP 350)

La condivisione dei dati di classe (CDS) è stata una caratteristica importante di Java HotSpot VM per un po 'di tempo. Consente la condivisione dei metadati di classe tra diverse JVM per ridurre il tempo di avvio e il footprint di memoria . JDK 10 ha esteso questa capacità aggiungendo CDS dell'applicazione (AppCDS), per dare agli sviluppatori la possibilità di includere classi di applicazioni nell'archivio condiviso. JDK 12 ha ulteriormente migliorato questa funzione per includere gli archivi CDS per impostazione predefinita.

Tuttavia, il processo di archiviazione delle classi di applicazioni era noioso. Per generare file di archivio, gli sviluppatori dovevano eseguire delle esecuzioni di prova delle loro applicazioni per creare prima un elenco di classi, quindi scaricarlo in un archivio. Successivamente, questo archivio potrebbe essere utilizzato per condividere i metadati tra le JVM.

Con l'archiviazione dinamica, JDK 13 ha semplificato questo processo. Ora possiamo generare un archivio condiviso nel momento in cui l'applicazione viene chiusa . Ciò ha eliminato la necessità di corse di prova.

Per consentire alle applicazioni di creare un archivio condiviso dinamico sopra l'archivio di sistema predefinito, è necessario aggiungere un'opzione -XX: ArchiveClassesAtExit e specificare il nome dell'archivio come argomento:

java -XX:ArchiveClassesAtExit= -cp  AppName

Possiamo quindi utilizzare l'archivio appena creato per eseguire la stessa app con l' opzione -XX: SharedArchiveFile :

java -XX:SharedArchiveFile= -cp  AppName

4. ZGC: Uncommit Unused Memory (JEP 351)

Z Garbage Collector è stato introdotto in Java 11 come meccanismo di garbage collection a bassa latenza, in modo tale che i tempi di pausa del GC non superassero mai i 10 ms. Tuttavia, a differenza di altri GC HotSpot VM come G1 e Shenandoah, non era attrezzato per restituire la memoria heap inutilizzata al sistema operativo. Java 13 ha aggiunto questa funzionalità a ZGC.

Ora otteniamo un footprint di memoria ridotto insieme a un miglioramento delle prestazioni.

A partire da Java 13, ZGC ora restituisce la memoria non salvata al sistema operativo per impostazione predefinita , fino al raggiungimento della dimensione heap minima specificata. Se non vogliamo utilizzare questa funzione, possiamo tornare alla modalità Java 11:

  • Utilizzando l'opzione -XX: -ZUncommit o
  • Impostazione delle dimensioni heap minimo ( -Xms ) e massimo ( -Xmx ) uguali

Inoltre, ZGC ora ha una dimensione heap massima supportata di 16 TB. In precedenza, il limite era di 4 TB.

5. Reimplementare l'API Legacy Socket (JEP 353)

Abbiamo visto le API Socket ( java.net.Socket e java.net.ServerSocket ) come parte integrante di Java sin dal suo inizio. Tuttavia, non sono mai stati modernizzati negli ultimi vent'anni. Scritti in Java e C precedenti, erano ingombranti e difficili da mantenere.

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

Inoltre, vengono proposte alcune API per la rimozione. Questi includono i tre metodi String sopra elencati e l' API javax.security.cert .

Tra le rimozioni vi sono lo strumento rmic e le vecchie funzionalità dello strumento JavaDoc. Anche le implementazioni SocketImpl precedenti a JDK 1.4 non sono più supportate.

7. Conclusione

In questo articolo, abbiamo visto tutte e cinque le proposte di miglioramento JDK implementate da Java 13. Abbiamo anche elencato alcune altre importanti aggiunte ed eliminazioni.

Come al solito, il codice sorgente è disponibile su GitHub.