Mantenendo la tradizione del ciclo semestrale, dopo il rilascio di Java 13 il 17 settembre 2019, è previsto il rilascio di Java 14, un’altra versione non-LTS, il 17 marzo 2020.
Java 14 Caratteristiche
Ecco la lista delle caratteristiche di Java 14:
- Switch Expressions (Standard) – JEP 361
- Pattern Matching per instanceof (Anteprima) – JEP 305
- NullPointerExceptions utili – JEP 358
- Records (Anteprima) – JEP 359
- Text Blocks (Seconda Anteprima) – JEP 368
- Strumento di confezionamento (Incubatore) – JEP 343
- Allocamento di memoria NUMA-Aware per G1 – JEP 345
- Streaming eventi JFR – JEP 349
- Buffer di byte mappati non volatili – JEP 352
- ZGC su macOS – JEP 364
- ZGC su Windows – JEP 365
- API di accesso alla memoria esterna (Incubatore) – JEP 370
Configurazione dell’installazione di Java 14 su macOS
- Per iniziare con Java 14, scarica il JDK da qui.
- Copia ed estrai il file tar nella cartella
/Library/Java/JavaVirtualMachines
come mostrato di seguito:
$ cd /Library/Java/JavaVirtualMachines
$ sudo cp ~/Downloads/openjdk-14_osx-x64_bin.tar.gz /Library/Java/JavaVirtualMachines
$ sudo tar xzf openjdk-14_osx-x64_bin.tar.gz
$ sudo rm openjdk-14_osx-x64_bin.tar.gz
Una volta fatto ciò, apri il bash_profile
utilizzando qualsiasi editor di testo. Sto utilizzando vim ~/.bash_profile
. Imposta il percorso di Java14 su JAVA_HOME, salva le modifiche e esegui un source ~/.bash_profile
per riflettere le modifiche.
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home
Infine, sei pronto per compilare ed eseguire programmi utilizzando Java 14. Utilizzeremo JShell, un tool interattivo REPL a riga di comando per testare rapidamente le nuove funzionalità di Java 14.
È importante notare che molte funzionalità rilasciate in Java 14 sono in anteprima. Ciò significa che, sebbene funzionino pienamente in questo momento, potrebbero essere modificate in futuro. Alcune potrebbero diventare uno standard o semplicemente essere rimosse nei prossimi cicli di rilascio. Per testare le funzionalità in anteprima, è necessario impostare esplicitamente --enable-preview
quando si esegue JShell o un programma Java come mostrato di seguito:
jshell --enable-preview
javac --release 14 --enable-preview Author.java
Nelle prossime sezioni, discuteremo alcune delle caratteristiche del linguaggio e della JVM.
Lettura consigliata: Installazione di Java 14 su Linux
1. Espressioni switch
Le espressioni switch, dopo essere state una funzionalità di anteprima nelle ultime due versioni – Java 12 e Java 13 – hanno finalmente ottenuto uno stato permanente in Java 14.
- Java 12 ha introdotto la sintassi delle lambda per le espressioni switch, consentendo così più etichette di caso per il confronto di pattern e prevenendo gli attraversamenti indesiderati che portano a un codice verboso. Ha anche imposto casi esaustivi, in cui viene generato un errore di compilazione se non vengono coperti tutti i casi di input.
- Java 13, nella seconda anteprima, ha introdotto le istruzioni
yield
al posto dibreak
per restituire valori da un’espressione.
Java 14 ha finalmente reso queste funzionalità uno standard ora.
String result = switch (day) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if(day.isEmpty())
yield "Please insert a valid day.";
else
yield "Looks like a Sunday.";
}
};
System.out.println(result);

Nota: Yield non è una nuova parola chiave in Java. Viene semplicemente utilizzata nelle espressioni switch.
2. Pattern Matching per instanceof (Anteprima)
Chiedi a qualsiasi sviluppatore Java di mostrarti il proprio codice e vedrai un ampio utilizzo di condizioni instanceof
in tutto il codice. In particolare, una verifica condizionale instanceof è generalmente seguita da un cast di tipo.
Java 14 si libera di questa verbosità rendendo l’estrazione condizionale molto più concisa.
Prima di Java 14:
if (obj instanceof Journaldev) {
Journaldev jd = (Journaldev) obj;
System.out.println(jd.getAuthor());
}
Da Java 14 in poi:
if (obj instanceof Journaldev jd) {
System.out.println(jd.getAuthor());
}
Nel codice sopra, l’istanza jd
verrebbe assegnata solo se obj
è di tipo Journaldev
. La variabile ha un’ambito limitato solo al blocco condizionale.
3. Eccezioni Null Pointer utili
Le eccezioni Null Pointer sono un incubo per qualsiasi sviluppatore. In precedenza, fino a Java 13, era complicato eseguire il debug delle famigerate NPE. Gli sviluppatori dovevano ricorrere ad altri strumenti di debug o trovare manualmente la variabile/metodo che era nulla poiché la traccia dello stack mostrava solo il numero di riga.
Prima di Java 14:
String name = jd.getBlog().getAuthor()
//Traccia dello stack
Exception in thread "main" java.lang.NullPointerException
at NullPointerExample.main(NullPointerExample.java:5)
Java 14 ha introdotto una nuova funzionalità JVM che fornisce una maggiore comprensione con una traccia dello stack più descrittiva come mostrato di seguito:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Blog.getAuthor()" because the return value of "Journaldev.getBlog()" is null
at NullPointerExample.main(NullPointerExample.java:4)
Nota: La funzionalità sopra non è una funzionalità del linguaggio. È un miglioramento nell’ambiente di runtime.
4. Records (Anteprima)
A record is a data class that stores pure data. The idea behind introducing records is to quickly create simple and concise classes devoid of boilerplate code.
Normalmente una classe in Java richiederebbe di implementare equals()
, hashCode()
, i metodi getter e setter. Anche se alcuni IDE supportano la generazione automatica di tali classi, il codice è comunque verboso. Con un record
è sufficiente definire una classe nel seguente modo.
record Author(){}
//o
record Author (String name, String topic) {}
Il compilatore Java genererà automaticamente un costruttore, campi finali privati, accessori, i metodi equals
/hashCode
e toString
. I metodi getter auto-generati della classe sopra sono name()
e topic()
.
Per esaminare il codice generato, utilizzare javap Author
dopo aver compilato il programma usando javac
. L’illustrazione seguente mostra la classe generata per record Author (String name, String topic) {}
:

La semantica dei Records è simile alle Data Classes in Kotlin
Inoltre, possiamo aggiungere campi aggiuntivi, metodi e costruttore al record nel seguente modo:
record Author (int id, String name, String topic) {
static int followers;
public static String followerCount() {
return "Followers are "+ followers;
}
public String description(){
return "Author "+ name + " writes on "+ topic;
}
public Author{
if (id < 0) {
throw new IllegalArgumentException( "id must be greater than 0.");
}
}
}
Il costruttore aggiuntivo definito all’interno del record è chiamato costruttore compatto. Non consiste in alcun parametro ed è solo un’estensione del costruttore canonico.
A compact constructor wouldn’t be generated as a separate constructor by the compiler. Instead, it is used for validation cases and would be invoked at the start of the main constructor.
Alcune cose importanti da notare sui Records:
- A record can neither extend a class nor it can be extended by another class. It’s a final class.
- I Records non possono essere astratti
- I Records non possono estendere nessun’altra classe e non possono definire campi di istanza all’interno del corpo. I campi di istanza devono essere definiti solo nella descrizione dello stato
- I campi dichiarati sono privati e finali
- Il corpo di un record consente campi e metodi statici
Lettura consigliata: Java Records
4.1) I valori all’interno dei campi di riferimento di un record possono essere mutati
È importante notare che per i campi definiti come oggetti, solo il riferimento è immutabile. I valori sottostanti possono essere modificati. L’illustrazione seguente mostra un record in cui l’ArrayList è modificato. Come puoi vedere, il valore viene modificato ogni volta che l’ArrayList viene cambiato.

4.2) I record possono implementare interfacce
Il seguente codice mostra un esempio di implementazione di un’interfaccia con i record:
record Author(String name, String topic) implements Information {
public String getFullName() {
return "Author "+ name + " writes on " + topic;
}
}
interface Information {
String getFullName();
}
Ecco l’output del codice sopra in azione in un JShell:

4.3) I record supportano più costruttori
I record consentono di dichiarare più costruttori con o senza parametri come mostrato di seguito:
record Author(String name, String topic) {
public Author() {
this("NA", "NA");
}
public Author(String name) {
this(name, "NA");
}
}
4.4) I record consentono la modifica dei metodi accessor
Anche se i record generano metodi accessor pubblici per i campi definiti nella descrizione dello stato, ti consentono anche di ridefinire i metodi accessor nel corpo come mostrato di seguito:
record Author(String name, String topic) {
public String name() {
return "This article was written by " + this.name;
}
}
4.5) Verifica Record e i suoi Componenti a Runtime
I record ci forniscono isRecord()
e getRecordComponents()
per verificare se la classe è un record e anche esaminare i suoi campi e tipi. L’illustrazione seguente mostra come viene fatto:

Anche se abbiamo aggiunto campi e metodi aggiuntivi al record negli esempi di codice sopra, assicurati di non esagerare. I record sono progettati come semplici portatori di dati e se stai cercando di implementare molti metodi aggiuntivi, è meglio tornare alla normale classe.
5. Blocchi di Testo (Anteprima)
I blocchi di testo sono stati introdotti come funzionalità di anteprima in Java 13 con l’obiettivo di consentire la facile creazione di stringhe letterali multilinea. È utile per la creazione semplice di stringhe HTML, JSON o di query SQL.
In Java 14, i blocchi di testo sono ancora in anteprima con alcune nuove aggiunte. Ora possiamo utilizzare:
- Il backslash per visualizzare blocchi di stringhe multilinea dall’aspetto piacevole.
\s
viene utilizzato per considerare gli spazi finali che vengono ignorati per impostazione predefinita dal compilatore. Conserva tutti gli spazi presenti prima di esso.
String text = """
Did you know \
Java 14 \
has the most features among\
all non-LTS versions so far\
""";
String text2 = """
line1
line2 \s
line3
""";
String text3 = "line1\nline2 \nline3\n"
// text2 e text3 sono uguali.
Riferimenti: OpenJDK 14
Source:
https://www.digitalocean.com/community/tutorials/java-14-features