Java 10 è il rilascio più veloce di una versione di Java nella sua storia di 23 anni. Java è stata criticata per la sua crescita e evoluzione lenta, ma Java 10 ha appena infranto questo concetto. Java 10 è un rilascio con molti cambiamenti futuristici, la portata e l’impatto dei quali potrebbero non essere evidenti ma sono di vasta portata. In questo articolo, discuteremo delle diverse caratteristiche aggiunte nel rilascio di Java 10. Prima di ciò, analizziamo alcuni cambiamenti introdotti nel modello di rilascio di Java.
Modello di supporto a lungo termine
A partire dal 2017, Oracle e la comunità Java hanno annunciato il passaggio a un nuovo ritmo di rilascio di 6 mesi per Java. Si è passati a un modello di supporto a lungo termine (LTS) per i prodotti Oracle Java SE. Cosa significa questo? Le versioni LTS dei prodotti offriranno supporto di primo piano e sostenuto da Oracle e saranno indirizzate ogni 3 anni. Ogni rilascio di Java è modellato su una o due funzionalità principali, queste funzionalità guidano il rilascio. Qualsiasi ostacolo posticipa il rilascio e lo porta sul mercato. Project Jigsaw è stata una funzionalità principale di Java 9, ha spostato le date di rilascio un paio di volte ed è stato ritardato di più di 1,5 anni. Il rilascio ogni 6 mesi seguirà un treno di rilascio. Il treno di rilascio avrà un programma ogni 6 mesi. Le funzionalità che superano la selezione vengono incluse nel treno; altrimenti, devono attendere il prossimo treno programmato.
Oracle JDK vs Open JDK
Per essere più amichevole per gli sviluppatori, la comunità di Oracle e Java ora promuove i binari di OpenJDK come JDK primario per il futuro. Questo è un grande sollievo rispetto ai giorni precedenti, in cui i binari JDK erano proprietari e concessi in licenza da Oracle, che aveva varie restrizioni sulla redistribuzione. Oracle continuerà comunque a produrre il proprio JDK, ma solo per le versioni a lungo termine. Questo è un passo verso una maggiore compatibilità con il cloud e i container, poiché i binari di Open JDK possono essere distribuiti come parte di un container. Cosa significa questo? I binari di Open JDK saranno rilasciati ogni 6 mesi, mentre i binari di Oracle JDK saranno rilasciati ogni 3 anni (versioni LTS). Quali binari JDK saranno adottati? Le grandi organizzazioni impiegano tempo a passare tra le versioni; si aggrappano alla versione fino a quando possono. L’adozione dell’industria per Java 6 è stata maggiore rispetto a Java 7 e poi l’industria si sta gradualmente spostando su Java 8. Secondo me, le versioni LTS saranno le più favorite dalle imprese. Tuttavia, se sarà la versione LTS di Oracle JDK o di Open JDK rimane da vedere, in parte perché c’è molto fermento nello spazio cloud. Java 9 e 10 non sono versioni LTS. Java 11, previsto per settembre 2018, sarà una versione LTS.
Caratteristiche di Java 10
Facciamo una sbirciata alle funzionalità disponibili in Java 10.
Con l’adozione del ciclo di rilascio basato sul tempo, Oracle ha modificato lo schema della stringa di versione della piattaforma Java SE e dell’JDK, insieme alle informazioni di versionamento correlate, per i modelli di rilascio basati sul tempo attuali e futuri. Il nuovo formato del numero di versione è: $FEATURE.$INTERIM.$UPDATE.$PATCH
$FEATURE: il contatore sarà incrementato ogni 6 mesi e sarà basato sulle versioni di rilascio delle funzionalità, ad esempio: JDK 10, JDK 11. $INTERIM: il contatore sarà incrementato per rilasci non legati alle funzionalità che contengono correzioni di bug e miglioramenti compatibili ma nessun cambiamento incompatibile. Di solito, questo sarà zero, poiché non ci saranno rilasci intermedi in un periodo di sei mesi. Questo è mantenuto per una revisione futura al modello di rilascio. $UPDATE: il contatore sarà incrementato per rilasci di aggiornamenti compatibili che correggono problemi di sicurezza, regressioni e bug nelle nuove funzionalità. Questo viene aggiornato un mese dopo il rilascio della funzionalità e ogni 3 mesi successivamente. Il rilascio di aprile 2018 è JDK 10.0.1, il rilascio di luglio è JDK 10.0.2 e così via. $PATCH: il contatore sarà incrementato per un rilascio di emergenza per correggere un problema critico. Nuove API sono state aggiunte per ottenere questi valori del contatore in modo programmato. Diamo un’occhiata;
Version version = Runtime.version();
version.feature();
version.interim();
version.update();
version.patch();
Ora, diamo un’occhiata al lanciatore di Java che restituisce le informazioni sulla versione:
$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)
Il formato del numero di versione è “10” poiché non c’è alcun altro contatore diverso da zero. La data di rilascio è aggiunta. Il 18.3 può essere letto come l’anno 2018 e il 3° mese, la build 10+46 è la 46ª build per la versione 10. Per una build ipotetica 93 di JDK 10.0.1, la build sarà 10.0.1+939. ### Inferenza del Tipo di Variabile Locale (JEP 286)
La tipizzazione locale automatica è la più grande nuova funzionalità in Java 10 per gli sviluppatori. Aggiunge l’inflessione di tipo alle dichiarazioni delle variabili locali con inizializzatori. L’inflessione del tipo locale può essere utilizzata solo nei seguenti scenari:
- Limitata solo alla variabile locale con inizializzatore
- Indici del ciclo for migliorato o indici
- Locale dichiarato nel ciclo for
Diamo un’occhiata al suo utilizzo:
var numbers = List.of(1, 2, 3, 4, 5); // inferred value ArrayList
// Indice del ciclo For migliorato
for (var number : numbers) {
System.out.println(number);
}
// Variabile locale dichiarata in un ciclo
for (var i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
Puoi leggere di più a riguardo nel nostro post esclusivo su l’inflessione del tipo di variabile locale Java 10 . 13. ### Compilatore JIT basato su Java sperimentale (JEP 317)
Questa funzione consente al compilatore JIT basato su Java, Graal, di essere utilizzato come compilatore JIT sperimentale sulla piattaforma Linux/x64. Questa è di gran lunga l’inclusione più futuristica nell’elenco delle funzionalità di Java 10. Graal è stato introdotto in Java 9. È un’alternativa al compilatore JIT a cui siamo abituati. È un plugin per la JVM, il che significa che il compilatore JIT non è legato alla JVM e può essere collegato dinamicamente e sostituito con qualsiasi altro plugin che sia conforme a JVMCI (Interfaccia del compilatore JVM a livello di Java). Porta anche la compilazione Ahead of Time (AOT) nel mondo di Java. Supporta anche l’interpretazione di linguaggi poliglotti. “Un compilatore Just in Time basato su Java scritto in Java per convertire il bytecode Java in codice macchina.” È confuso? Se la JVM è scritta in Java, allora non hai bisogno di una JVM per eseguire la JVM? La JVM può essere compilata AOT e quindi il compilatore JIT può essere utilizzato all’interno della JVM per migliorare le prestazioni attraverso l’ottimizzazione del codice live. Graal è una riscrittura completa del compilatore JIT in Java da zero. Il compilatore JIT precedente era scritto in C++. È considerato uno degli ultimi stadi dell’evoluzione per qualsiasi linguaggio di programmazione. Puoi passare a Graal con i seguenti parametri jvm:
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
Puoi saperne di più su Graal dalla presentazione di Chris Seaton.
Questa funzione aiuta a migliorare l’impronta di avvio, estendendo la funzione di condivisione di dati di classe esistente (“CDS”) per consentire alle classi dell’applicazione di essere collocate nell’archivio condiviso. La JVM, durante l’avvio, esegue alcune fasi preliminari, una delle quali è il caricamento delle classi in memoria. Se ci sono diversi file JAR con molte classi, il ritardo nella prima richiesta è chiaramente visibile. Questo diventa un problema con l’architettura senza server, dove il tempo di avvio è critico. Per ridurre il tempo di avvio dell’applicazione, può essere utilizzata la condivisione di dati di classe dell’applicazione. L’idea è ridurre l’impronta condividendo i metadati delle classi comuni tra diversi processi Java. Ciò può essere ottenuto attraverso i seguenti 3 passaggi: Determinare le classi da archiviare: Utilizzare il launcher Java per creare un elenco di file da archiviare, ciò può essere ottenuto attraverso i seguenti parametri:
$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld
Creare l’archivio AppCDS: Utilizzare il launcher Java per creare l’archivio dell’elenco di file da utilizzare per l’Application CDS, ciò può essere ottenuto attraverso i seguenti parametri:
$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar
Utilizzare l’archivio AppCDS: Utilizzare il launcher Java con i seguenti parametri per utilizzare l’Application CDS.
$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld
Il G1 garbage collector è diventato predefinito in JDK 9. Il garbage collector G1 evita qualsiasi garbage collection completa, ma quando i thread concorrenti per la raccolta non riescono a recuperare la memoria abbastanza velocemente, l’esperienza degli utenti ne risente. Questo cambiamento migliora la latenza peggiore del G1 rendendo il GC completo parallelo. L’algoritmo di mark-sweep-compact del raccoglitore G1 è parallelizzato come parte di questa modifica e verrà attivato quando i thread concorrenti per la raccolta non riescono a recuperare la memoria abbastanza velocemente. 25. ### Interfaccia del Garbage Collector (JEP 304)
Questa JEP è un cambiamento futuristico. Migliora l’isolamento del codice dei diversi garbage collector introducendo un’interfaccia comune del Garbage Collector. Questo cambiamento fornisce una migliore modularità al codice GC interno. Aiuterà in futuro ad aggiungere nuovi GC senza modificare il codice esistente, aiuterà anche nella rimozione o nella manutenzione dei GC precedenti. 26. ### Ulteriori Estensioni di Tag di Lingua Unicode (JEP 314)
Questa funzionalità migliora java.util.Locale e le API correlate per implementare ulteriori estensioni Unicode dei tag di lingua BCP 47. A partire da Java SE 9, le estensioni dei tag di lingua BCP 47 U supportate sono “ca” e “nu”. Questa JEP aggiungerà il supporto per le seguenti estensioni aggiuntive:
- cu (tipo di valuta)
- fw (primo giorno della settimana)
- rg (sovrascrittura della regione)
- fuso orario
Per supportare queste estensioni aggiuntive, sono state apportate modifiche a varie API per fornire informazioni basate su U o estensioni aggiuntive.
java.text.DateFormat::get*Instance
java.text.DateFormatSymbols::getInstance
java.text.DecimalFormatSymbols::getInstance
java.text.NumberFormat::get*Instance
java.time.format.DateTimeFormatter::localizedBy
java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern
java.time.format.DecimalStyle::of
java.time.temporal.WeekFields::of
java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}
java.util.Currency::getInstance
java.util.Locale::getDisplayName
java.util.spi.LocaleNameProvider
Per promuovere OpenJDK e renderlo più appetibile per gli utenti della comunità, questa funzionalità fornisce un set predefinito di certificati dell’Autorità di Certificazione (CA) radice nel JDK. Ciò significherà anche che le versioni binarie di Oracle & Open JDK saranno funzionalmente identiche. Componenti critici della sicurezza come TLS funzioneranno per impostazione predefinita nelle build di OpenJDK in futuro. 30. ### Handshakes Thread-Local (JEP 312)
Questa è una funzionalità interna della JVM per migliorare le prestazioni. Un’operazione di handshake è una chiamata di callback che viene eseguita per ogni JavaThread mentre quel thread è in uno stato di safepoint. La callback viene eseguita sia dal thread stesso che dal thread VM mantenendo il thread in uno stato bloccato. Questa funzionalità fornisce un modo per eseguire una chiamata di callback sui thread senza eseguire un safepoint globale VM. Rende possibile ed economico fermare i singoli thread e non solo tutti i thread o nessuno. 31. ### Assegnazione della Memoria Heap su Dispositivi di Memoria Alternativi (JEP 316)
Le applicazioni sono diventate sempre più esigenti in termini di memoria, c’è un aumento delle applicazioni native del cloud, dei database in memoria, delle applicazioni di streaming. Per soddisfare queste esigenze, sono disponibili diverse architetture di memoria. Questa funzionalità migliora la capacità di HotSpot VM di allocare l’heap degli oggetti Java su un dispositivo di memoria alternativo, come ad esempio un NV-DIMM, specificato dall’utente. Questo JEP si rivolge a dispositivi di memoria alternativi che hanno le stesse semantiche della DRAM, comprese le semantiche delle operazioni atomiche, e possono quindi essere utilizzati al posto della DRAM per l’heap degli oggetti senza alcuna modifica al codice dell’applicazione esistente.32. ### Rimuovi lo strumento di generazione dell’header nativo – javah (JEP 313)
Si tratta di un cambiamento di manutenzione per rimuovere lo strumento javah dal JDK. La funzionalità dello strumento è stata aggiunta in javac
come parte di JDK 8, che consente di scrivere file di intestazione nativi durante la compilazione, rendendo inutile javah.35. ### Consolidare la foresta JDK in un singolo repository (JEP 296)
Nel corso degli anni sono stati creati vari repository Mercurial per il codice di JDK. I diversi repository offrono alcuni vantaggi, ma hanno anche vari svantaggi operativi. Come parte di questo cambiamento, numerosi repository della foresta JDK vengono combinati in un singolo repository al fine di semplificare e ottimizzare lo sviluppo.36. ### Modifiche all’API
Java 10 ha aggiunto e rimosso (sì, non è un errore di battitura) alcune API. Java 9 ha introdotto la deprecazione avanzata, dove alcune API sono state contrassegnate per essere rimosse nelle future versioni. API Rimosse: Puoi trovare le API rimosse qui. API Aggiunte: Sono state aggiunte 73 nuove API in Java 10. Puoi trovare le API aggiunte insieme a un confronto qui. Esaminiamo alcune aggiunte:
- Sono stati aggiunti gli interfacce List, Map e Set con un metodo statico copyOf(Collection). Restituisce una List, Map o Set non modificabile contenente gli elementi forniti. Per una List, se la List data viene successivamente modificata, la List restituita non rifletterà tali modifiche.
- Optional e le sue varianti primitive ottengono un metodo orElseThrow(). Questo è esattamente come get(), tuttavia il javadoc afferma che è un’alternativa preferita rispetto a get().
- La classe Collectors ottiene vari metodi per la raccolta di collezioni non modificabili (Set, List, Map).
List actors = new ArrayList<>();
actors.add("Jack Nicholson");
actors.add("Marlon Brando");
System.out.println(actors); // prints [Jack Nicholson, Marlon Brando]
// Nuova API aggiunta - Crea una List non modificabile da una List.
List copyOfActors = List.copyOf(actors);
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
// copyOfActors.add("Robert De Niro"); Genererà un
// UnsupportedOperationException..
actors.add("Robert De Niro");
System.out.println(actors);// prints [Jack Nicholson, Marlon Brando, Robert De Niro]
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
String str = "";
Optional name = Optional.ofNullable(str);
// Nuova API aggiunta - è l'opzione preferita rispetto al metodo get().
name.orElseThrow(); // same as name.get()
// Nuova API aggiunta - Collectors.toUnmodifiableList.
List collect = actors.stream().collect(Collectors.toUnmodifiableList());
// collect.add("Tom Hanks"); // Genererà un
// UnsupportedOperationException..
Conclusione
In questo articolo, abbiamo esaminato le diverse nuove funzionalità aggiunte in Java 10. Se pensi che qui sia stato trascurato qualcosa di importante, per favore faccelo sapere tramite i commenti. Come al solito, puoi controllare il codice completo su GitHub qui.
Source:
https://www.digitalocean.com/community/tutorials/java-10-features