Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Java 12 disponible avec les expressions Switch
Un nouveau récupérateur de mémoire à faible temps de pause et diverses améliorations pour G1

Le , par Michael Guilloux

324PARTAGES

12  0 
Après la sortie de Java 9 en septembre 2017, Oracle a adopté un nouveau cycle de publication de six mois : une nouvelle version en mars et septembre de chaque année et une version LTS tous les 18 mois. Les versions intermédiaires seront donc des mises à jour de fonctionnalités qui ne se seront prises en charge que pendant 6 mois, le temps que la prochaine version arrive. Conformément à ce nouveau timing, Oracle vient d'annoncer la sortie de Java 12.

La nouvelle version apporte un certain nombre de nouvelles fonctionnalités et d’améliorations remarquables. Plus précisément, Java 12 inclut une nouvelle fonctionnalité de langage, les expressions Switch (en préversion), un nouveau récupérateur de mémoire à faible temps de pause appelé Shenandoah (expérimental) et diverses améliorations au récupérateur de mémoire par défaut Garbage First (G1). En tout, Java 12 introduit huit principales améliorations (JEP) que nous présentons ici.

Expressions Switch

Cette fonctionnalité en préversion étend l'instruction Switch afin qu'elle puisse être utilisée également en tant qu'expression. Le Switch n'est donc plus juste une structure de contrôle (comme les if/else), mais peut maintenant renvoyer une valeur. Avec cette fonctionnalité vient aussi une nouvelle syntaxe plus pratique et plus concise qui utilise l'opérateur arrow (->), et qui supprime le besoin d’instructions break. Précisons que seul le code à droite de -> est exécuté.

Ci-dessous un exemple de code avec le Switch classique : les nombreuses instructions break dans le code le rendent inutilement verbeux, ce qui peut souvent masquer des erreurs de débogage difficiles à identifier.

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  
switch (day) { 
    case MONDAY: 
    case FRIDAY: 
    case SUNDAY: 
        System.out.println(6); 
        break; 
    case TUESDAY: 
        System.out.println(7); 
        break; 
    case THURSDAY: 
    case SATURDAY: 
        System.out.println(8); 
        break; 
    case WEDNESDAY: 
        System.out.println(9); 
        break; 
}


Le code précédent peut être réécrit comme suit avec la nouvelle syntaxe utilisant -> et sans break :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
  
switch (day) { 
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); 
    case TUESDAY                -> System.out.println(7); 
    case THURSDAY, SATURDAY     -> System.out.println(8); 
    case WEDNESDAY              -> System.out.println(9); 
}


Code avec expression Switch :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
  
int numLetters = switch (day) { 
    case MONDAY, FRIDAY, SUNDAY -> 6; 
    case TUESDAY                -> 7; 
    case THURSDAY, SATURDAY     -> 8; 
    case WEDNESDAY              -> 9; 
};


Collectes mixtes annulables pour G1

Il s'agit ici de pouvoir avorter les collectes G1 mixtes si elles risquent de dépasser la cible de pause. Si cela est nécessaire pour respecter la cible de temps de pause fournie par l'utilisateur, G1 (Garbage First) sera en effet contraint d'abandonner le processus de récupération de mémoire. Pour cela, le jeu de régions dans lesquelles la récupération de mémoire sera effectuée est divisé en parties obligatoires et facultatives. Ce qui permet à G1 d'avorter le processus de récupération des parties facultatives si le temps de pause n’est pas respecté.


Renvoi immédiat de la mémoire non utilisée par G1 au système d'exploitation

Java 12 améliore le récupérateur de mémoire G1 afin de renvoyer automatiquement le tas Java (la mémoire heap) au système d'exploitation. Il s'agissait en effet de faire en sorte que G1 renvoie les zones de mémoire collectées au système d'exploitation après une période de faible activité de l'application. Jusqu'à présent, G1 ne renvoyait la mémoire au système d’exploitation qu’après un Full GC, chose qu’il évitait d'ailleurs, car l'un des objectifs d’une JVM correctement paramétrée est d’avoir le moins de Full GC possible. Ce qui fait qu'en général, le récupérateur de mémoire G1 ne retournait pas du tout la mémoire effacée vers le système d’exploitation.

Archives CDS par défaut

Class Data Sharing (CDS) est une fonctionnalité de la JVM qui permet de réduire le temps de démarrage de celle-ci, en enregistrant dans un fichier les métadonnées des classes pour une réutilisation lors du prochain lancement de la JVM. Toutefois, si vous n'installez pas le JRE avec le programme d'installation, l'archive CDS n'est pas générée par défaut et la commande java -Xshare:dump doit être exécutée manuellement. Dans Java 12, les archives CDS seront générées par défaut sur les plateformes 64 bits, pas besoin d’argument spécifique dans la ligne de commande.

Un seul port ciblant l'architecture ARM 64 bits

Il existe deux ensembles différents de codes source (donc de ports) ciblant ARM 64 bits dans le JDK. L'un, fourni par Oracle, est arm64 (disponible dans le répertoire src/hotspot/cpu/arm) et l'autre est aarch64 (disponible dans le répertoire open/src/hotspot/cpu/aarch64). Dans Java 12, il y aura désormais un seul port ciblant l'architecture ARM 64 bits. Toutes les sources liées au port arm64 ont été supprimées tout en conservant le port ARM 32 bits et le port aarch64. La suppression d'un port 64 bits permettra à tous les contributeurs de concentrer leurs efforts sur une implémentation ARM 64 bits unique et d’éliminer le travail en double requis pour la maintenance de deux ports.

API de constantes JVM

Java 12 introduit une API pour modéliser les descriptions nominales des fichiers de classe clé et artefacts de runtime, en particulier des constantes pouvant être chargées à partir du pool de constantes.

Shenandoah, un ramasse-miettes à faible temps de pause

Java 12 ajoute un nouvel algorithme de récupération de mémoire réduisant les temps de pause du GC en effectuant le travail d'évacuation en même temps que les threads Java en cours d'exécution. Développé par Redhat et déjà inclus depuis plusieurs mois dans leur JVM, Shenandoah est intégré en tant que fonctionnalité expérimentale dans Java 12. Les temps de pause avec Shenandoah sont indépendants de la taille du tas, ce qui signifie que vous aurez les mêmes temps de pause, que votre tas soit de 200 Mo ou de 200 Go.

Suite de microbenchmarks

Java 12 vient avec une suite de base de microbenchmarks introduite au code du JDK. Les développeurs peuvent facilement exécuter les microbenchmarks existants et en créer de nouveaux.

Pas de littéraux de chaîne bruts (Raw String Literals)

Enfin, rappelons que les littéraux de chaîne bruts (Raw String Literals) ont été supprimées du JDK 12. Les littéraux de chaîne bruts facilitent l'utilisation de chaînes contenant des caractères spéciaux et des chaînes multilignes. Ils sont créés avec le symbole backtick (accent grave) : `. Il s'agissait également d'introduire la fonction String::align pour faciliter l’utilisation de texte multiligne indenté et les fonctions unescape/escape pour les conversions vers ou à partir de littéraux de chaîne (traditionnels). Mais cette fonctionnalité qui était prévue pour le JDK 12 a été supprimée au dernier moment. Elle pourrait réapparaître dans les versions à venir.

Source : Blog Oracle

Et vous ?

Que pensez-vous des nouveautés et améliorations de Java 12 ?
Lesquelles appréciez-vous le plus et pourquoi ?
Comptez-vous migrer vers cette version ou attendre la prochaine LTS ?

Voir aussi :

JavaFX disponible en version 12, la boite à outils graphique suit l'évolution de Java
Quelle version de Java utilisez-vous ? Qu'est-ce qui vous empêche de migrer vers une version plus récente ?
Java : une version à accès anticipé du JDK 13 est publiée, Oracle veut unifier les deux méthodes de la classe GraphicsEnvironment
Java : Oracle publie la première release candidate du JDK 12, avec toutes les fonctionnalités majeures annoncées sauf les littéraux de chaînes bruts
Quelles implémentations JPA (Java Persistence API) utilisez-vous et pourquoi ? Partagez votre expérience

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de Mickael_Istria
Membre émérite https://www.developpez.com
Le 21/03/2019 à 11:05
C'est justement l'occasion ou jamais d'apprendre a utiliser un IDE open-source et durable
3  0 
Avatar de bouye
Rédacteur/Modérateur https://www.developpez.com
Le 20/03/2019 à 23:32
A noter que l'expression switch supporte également les blocs multi-lignes entre {} et qu'il faut alors utiliser l'instruction break pour faire un retour de la valeur.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
    public void assignValue(Size size) {
        int height = 0;
        height = switch(size) {
            case S -> 18;
            case M -> {
                    int weight = 19;
                    break (weight > 10 ? 15 : 20); 
                } 
            case L, XL -> 25;
        };
    }
A noter de plus qu'il ne s'agit pas la d'une fonctionnalité définitive mais d'une fonctionnalité en aperçu (Preview Language and VM Features), ce qui veut dire que oui elle est bien complète et fonctionnelle mais peut être modifiée ou retirée d'un prochain JDK si jamais il s’avère qu'elle cause trop de soucis.

Citation Envoyé par http://openjdk.java.net/jeps/12
A preview language or VM feature is a new feature of the Java SE Platform that is fully specified, fully implemented, and yet impermanent. It is available in a JDK feature release to provoke developer feedback based on real world use; this may lead to it becoming permanent in a future Java SE Platform.
Source : blog de intellij sur le support des switch expression dans Intellij 2019.1 disponible en Early Access (la version 2018.3 fonctionne avec le JDK 12 mais ne supporte pas cette syntaxe)

EDIT - Avis perso : je pense que syntaxiquement c’était une erreur de choisir break et que return aurait été plus le bienvenu a cet endroit. Même si le mécanisme sous-jacent est probablement différent de celui des méthode, lambda et autres classe anonyme et qu'il ont fait ce choix pour des raisons d’analyse syntaxique ou de compilateur, il semble plus logique pour le programmeur moyen que la valeur renvoyée par un bloc, quel qu'il soit, se fasse de manière unifiée par une instruction return. D'un autre cote il s'agit aussi d'un bloc d'expression comme pour similaire a un for ou un while et donc ça pourrait poser le soucis que ça laisserait penser a ce que cette instruction sorte de la méthode englobant le switch.
1  0 
Avatar de bouye
Rédacteur/Modérateur https://www.developpez.com
Le 21/03/2019 à 12:51
J'ai la version 2018.3 Community de Intellij IDEA et il fonctionne très bien avec les JDK 9, 10, 11 et 12 juste qu'il ne supporte le switch expression. La version 2019.1 qui est dispo sur le canal early access est sensé le supporter. Intellij IDEA ne supporte pas JLink par contre. Le supporte des modules fonctionne plutôt bien dans Intellij.

Apache NetBeans 10 supporte les JDK 8, 9 et 10 mais pas trop 11 il me semble (à vérifier) et encore moins le 12 (il me semble que c'est prévu pour NetBeans 11 d'après la roadmap chez Apache). Apache NetBeans supporte JLink et couplé avec le JDK 8 supporte très bien javapackager. Le support des modules est défaillant dans Apache NetBbeans lorsqu'on utilise des legacy jar avec noms de modules auto-générés, pour une raison que je ne m'explique pas Apache NetBeans n'utilise pas la même règle de génération de nom de module que le JDK.
1  0 
Avatar de atha2
Membre éprouvé https://www.developpez.com
Le 21/03/2019 à 0:55
Citation Envoyé par bouye Voir le message
A noter que l'expression switch supporte également les blocs multi-lignes entre {} et qu'il faut alors utiliser l'instruction break pour faire un retour de la valeur.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
    public void assignValue(Size size) {
        int height = 0;
        height = switch(size) {
            case S -> 18;
            case M -> {
                    int weight = 19;
                    break (weight > 10 ? 15 : 20); 
                } 
        };
    }
EDIT - Avis perso : je pense que syntaxiquement c’était une erreur de choisir break et que return aurait été plus le bienvenu a cet endroit. Même si le mécanisme sous-jacent est probablement différent de celui des méthode, lambda et autres classe anonyme et qu'il ont fait ce choix pour des raisons d’analyse syntaxique ou de compilateur, il semble plus logique pour le programmeur moyen que la valeur renvoyée par un bloc, quel qu'il soit, se fasse de manière unifiée par une instruction return. D'un autre cote il s'agit aussi d'un bloc d'expression comme pour similaire a un for ou un while et donc ça pourrait poser le soucis que ça laisserait penser a ce que cette instruction sorte de la méthode englobant le switch.
J'imagine que les parenthèse sont optionnelles et qu'on peut écrire :
Code : Sélectionner tout
1
2
break weight > 10 ? 15 : 20;
?
Perso sans parler de l'aspect technique qui ne me parait pas pertinent dans le choix du mot clé, le choix du mot clé "break" me parait plus pertinent que "return". Pour interrompre le file d’exécution d'une méthode, on utilise le mot clé "return". Pour interrompe le file d’exécution d'une structure de contrôle (while, for switch), on utilise "for" (voir "continue".

Sinon plutôt (ou en complément) que break une autre syntaxe pourrait être pertinente :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
    public void assignValue(Size size) {
        int height = 0;
        height = switch(size) {
            case S -> 18;
            case M -> {
                    int weight = 19;
                    weight > 10 ? 15 : 20; 
                } 
        };
    }
Comme dans pas mal de langage fonctionnel, l'évaluation d'un bloc d'instruction correspond à l’évaluation de la dernière instruction de ce bloc. Mais j'imagine qu'autoriser ça dans ce contexte forcerai à modifier le comportement des lambdas et du "return" classique afin d'uniformiser le langage.
0  0 
Avatar de DaTheWolf
Membre du Club https://www.developpez.com
Le 21/03/2019 à 7:35
Voilà,

Pour les nouveautés ça a l'air chouette. Surtout l'amélioration du GC, qui me laisse espérer pour certains de mes projets.
Mon problème est que j'utilise un IDE payant, et je ne peux pas renouveler ma licence pour l'instant. L'IDE JetBrains ne reconnaît la string de version "10" "11" "12" parce que ... raison commerciale certainement en 2019.

Connaissez-vous un patch? Parce que Eclipse et Netbeans je ne sais pas les utiliser.

PS il y a bien une version gratuite des produits JetBrains pour une utilisation libre (ce qui est mon cas) mais apparemment quand on a payé une licence on ne sait pas rétrograder.
0  0 
Avatar de tomlev
Rédacteur/Modérateur https://www.developpez.com
Le 25/03/2019 à 12:51
Les expressions switch ressemblent comme deux gouttes d'eau à celles qui arrivent en C# 8 (juste les flèches qui sont différentes : "->" en Java, "=>" en C#). Quant à savoir qui a copié l'autre, je ne m'avancerai pas... de toute façon Java et C# se sont toujours piqué des idées
0  0 
Avatar de Mickael_Istria
Membre émérite https://www.developpez.com
Le 25/03/2019 à 13:11
Eclipse IDE 2019-03 supporte bien Java 12 (et les switch expressions) en lui ajoutant cette extension: https://marketplace.eclipse.org/cont...se-2019-03-411
0  0