Suivant la tradition du cycle de six mois, après la sortie de Java 13 le 17 septembre 2019, Java 14, une autre version non LTS, est prévue pour le 17 mars 2020.
Fonctionnalités de Java 14
Voici la liste des fonctionnalités de Java 14 :
- Expressions Switch (Standard) – JEP 361
- Correspondance de motifs pour instanceof (Aperçu) – JEP 305
- Exceptions NullPointerExceptions utiles – JEP 358
- Enregistrements (Aperçu) – JEP 359
- Blocs de texte (Deuxième Aperçu) – JEP 368
- Outil de packaging (Incubateur) – JEP 343
- Allocation de mémoire consciente de NUMA pour G1 – JEP 345
- Diffusion d’événements JFR – JEP 349
- Tampons de bytes mappés non volatiles – JEP 352
- ZGC sur macOS – JEP 364
- ZGC sur Windows – JEP 365
- API d’accès à la mémoire externe (Incubateur) – JEP 370
Configuration de l’installation de Java 14 sur macOS
- Pour commencer avec Java 14, téléchargez le JDK depuis ici.
- Copiez et extrayez le fichier tar dans le
/Library/Java/JavaVirtualMachines
comme indiqué ci-dessous :
$ 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
Une fois cela fait, ouvrez le fichier bash_profile
à l’aide de n’importe quel éditeur de texte. J’utilise vim ~/.bash_profile
. Définissez le chemin de Java14 comme JAVA_HOME, enregistrez les modifications et exécutez source ~/.bash_profile
pour refléter les changements.
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home
Enfin, vous êtes prêt à compiler et exécuter des programmes en utilisant Java 14. Nous utiliserons JShell, un outil de ligne de commande REPL interactif pour tester rapidement les nouvelles fonctionnalités de Java 14.
Il est important de noter que de nombreuses fonctionnalités publiées dans Java 14 sont en mode prévisualisation. Cela signifie que bien qu’elles fonctionnent parfaitement maintenant, des modifications peuvent être apportées à l’avenir. Certaines pourraient devenir une norme ou simplement être supprimées dans les prochains cycles de publication. Pour tester les fonctionnalités de prévisualisation, vous devez explicitement définir --enable-preview
lors de l’exécution de JShell ou du programme Java comme indiqué ci-dessous :
jshell --enable-preview
javac --release 14 --enable-preview Author.java
Dans les prochaines sections, discutons de certaines des fonctionnalités du langage et de la JVM.
Lecture recommandée: Installation de Java 14 sur Linux
1. Expressions Switch
Les expressions switch, après avoir été une fonctionnalité de prévisualisation lors des deux dernières versions – Java 12 et Java 13, ont enfin obtenu le statut permanent dans Java 14.
- Java 12 a introduit la syntaxe lambda pour les expressions switch, permettant ainsi plusieurs étiquettes de cas pour la correspondance de motifs, tout en évitant les chutes à travers qui conduisent à un code verbeux. Il a également imposé des cas exhaustifs, où une erreur de compilation serait générée si tous les cas d’entrée ne sont pas couverts.
- Java 13, la deuxième prévisualisation, a introduit des déclarations
yield
au lieu debreak
pour retourner des valeurs à partir d’une expression.
Java 14 a finalement élevé ces fonctionnalités au statut de norme maintenant.
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);

Note: « Yield » n’est pas un nouveau mot-clé en Java. Il est simplement utilisé dans les expressions switch.
2. Correspondance de motifs pour instanceof (Prévisualisation)
Demandez à n’importe quel développeur Java de montrer leur base de code, et vous verrez une bonne utilisation des conditions instanceof
partout dans le code. En particulier, une vérification conditionnelle instanceof
est généralement suivie d’une conversion de type.
Java 14 élimine cette verborrhée en rendant l’extraction conditionnelle beaucoup plus concise.
Avant Java 14 :
if (obj instanceof Journaldev) {
Journaldev jd = (Journaldev) obj;
System.out.println(jd.getAuthor());
}
Java 14 et au-delà :
if (obj instanceof Journaldev jd) {
System.out.println(jd.getAuthor());
}
Dans le code ci-dessus, l’instance jd
ne serait assignée que si obj
est du type Journaldev
. La portée de la variable est limitée au bloc conditionnel uniquement.
3. Helpful NullPointerExceptions
Les exceptions Null Pointer sont un cauchemar pour tout développeur. Auparavant, jusqu’à Java 13, il était difficile de déboguer les NPEs infâmes. Les développeurs devaient recourir à d’autres outils de débogage ou trouver manuellement la variable/méthode qui était nulle, car la trace de la pile ne montrait que le numéro de ligne.
Avant Java 14 :
String name = jd.getBlog().getAuthor()
//Trace de la pile
Exception in thread "main" java.lang.NullPointerException
at NullPointerExample.main(NullPointerExample.java:5)
Java 14 a introduit une nouvelle fonctionnalité JVM qui offre de meilleures informations avec une pile plus descriptive comme indiqué ci-dessous :
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)
Remarque : La fonctionnalité ci-dessus n’est pas une caractéristique du langage. Il s’agit d’une amélioration de l’environnement d’exécution.
4. Records (Aperçu)
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.
Normalement, une classe en Java vous obligerait à implémenter equals()
, hashCode()
, les méthodes getters et setters. Bien que certains IDE prennent en charge la génération automatique de telles classes, le code reste verbeux. Avec un record
, vous devez simplement définir une classe de la manière suivante.
record Author(){}
//ou
record Author (String name, String topic) {}
Le compilateur Java générera automatiquement un constructeur, des champs finaux privés, des accesseurs, les méthodes equals
/hashCode
et toString
. Les méthodes getter générées automatiquement pour la classe ci-dessus sont name()
et topic()
.
Pour examiner le code généré, utilisez javap Author
après avoir compilé le programme avec javac
. L’illustration suivante montre la classe générée pour record Author (String name, String topic) {}
:

La sémantique des Records est similaire aux Classes de données en Kotlin
De plus, nous pouvons ajouter des champs, des méthodes et un constructeur supplémentaires au record de la manière suivante:
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.");
}
}
}
Le constructeur supplémentaire défini à l’intérieur du record est appelé constructeur compact. Il ne comprend aucun paramètre et est simplement une extension du constructeur canonique.
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.
Quelques points importants à noter sur les Records:
- A record can neither extend a class nor it can be extended by another class. It’s a final class.
- Les Records ne peuvent pas être abstraits
- Les Records ne peuvent pas étendre une autre classe et ne peuvent pas définir de champs d’instance à l’intérieur du corps. Les champs d’instance doivent être définis uniquement dans la description de l’état
- Les champs déclarés sont privés et final
- Le corps d’un record autorise les champs et méthodes statiques
Lecture recommandée: Java Records
4.1) Les valeurs à l’intérieur des champs de référence d’un enregistrement peuvent être mutées
Il est important de noter que pour les champs définis comme objets, seule la référence est immuable. Les valeurs sous-jacentes peuvent être modifiées. L’illustration suivante montre un enregistrement dans lequel l’ArrayList est modifié. Comme vous pouvez le voir, la valeur est modifiée chaque fois que l’ArrayList est modifié.

4.2) Les enregistrements peuvent implémenter des interfaces
Le code suivant montre un exemple d’implémentation d’une interface avec des enregistrements:
record Author(String name, String topic) implements Information {
public String getFullName() {
return "Author "+ name + " writes on " + topic;
}
}
interface Information {
String getFullName();
}
Voici la sortie du code ci-dessus en action dans un JShell:

4.3) Les enregistrements prennent en charge plusieurs constructeurs
Les enregistrements permettent de déclarer plusieurs constructeurs avec ou sans paramètres comme indiqué ci-dessous:
record Author(String name, String topic) {
public Author() {
this("NA", "NA");
}
public Author(String name) {
this(name, "NA");
}
}
4.4) Les enregistrements permettent de modifier les méthodes d’accesseur
Bien que les enregistrements génèrent des méthodes d’accesseur publiques pour les champs définis dans la description de l’état, ils vous permettent également de redéfinir les méthodes d’accès dans le corps comme indiqué ci-dessous :
record Author(String name, String topic) {
public String name() {
return "This article was written by " + this.name;
}
}
4.5) Vérifier l’enregistrement et ses composants à l’exécution
Les enregistrements nous fournissent les fonctions isRecord()
et getRecordComponents()
pour vérifier si la classe est un enregistrement et aussi pour examiner ses champs et types. L’illustration suivante montre comment cela est fait :

Même si nous avons ajouté des champs et des méthodes supplémentaires à l’enregistrement dans les exemples de code ci-dessus, assurez-vous de ne pas en faire trop. Les enregistrements sont conçus comme des transporteurs de données brutes et si vous souhaitez implémenter de nombreuses méthodes supplémentaires, il est préférable de revenir à la classe normale.
5. Blocs de texte (Aperçu)
Les blocs de texte ont été introduits en tant que fonctionnalité de prévisualisation dans Java 13 dans le but de permettre la création facile de littéraux de chaînes de caractères sur plusieurs lignes. C’est utile pour créer facilement des chaînes de caractères HTML, JSON ou de requête SQL.
En Java 14, les blocs de texte sont toujours en prévisualisation avec quelques nouveautés. Nous pouvons maintenant utiliser:
- Le backslash pour afficher des blocs de chaînes de caractères sur plusieurs lignes au rendu agréable.
\s
est utilisé pour considérer les espaces de fin de ligne qui sont par défaut ignorés par le compilateur. Il préserve tous les espaces présents avant lui.
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 et text3 sont égaux.
Références: OpenJDK 14
Source:
https://www.digitalocean.com/community/tutorials/java-14-features