Nous sommes déjà habitués au fait qu'une nouvelle version du JDK apparaît tous les six mois. Jusqu'à présent, cette approche s'est justifiée, et les craintes de certains développeurs de ne pas suivre les mises à jour ont été vaines : il y a peu de changements semestriels et ils ne sont pas aussi globaux qu'avant. Eh bien, les programmeurs débutants ne remarqueront peut-être pas du tout l'innovation. Cependant, il est préférable pour les futurs développeurs de logiciels de se tenir au courant des innovations. Dans cet article, nous décrirons traditionnellement les propositions d’extension acceptées (JEP). Java 13 ne comprend que cinq JEP et 76 nouveaux éléments de bibliothèque de base (dont près de la moitié sont de simples ajouts au package java.io).
JEP 355 : Blocs de texte (Aperçu)
Commençons par changer la syntaxe du langage. Les plus importants d'entre eux sont les blocs de texte. Ils permettent d'éviter les caractères d'échappement et de savoir formater les chaînes. Vous vous souvenez peut-être que le JDK 12 n'incluait pas la fonctionnalité attendue de littéraux de chaîne brute (JEP 326) pour travailler avec des littéraux de chaîne. En Java 13, il a été remplacé par JEP 355 avec ses blocs de texte. Vous vous souvenez probablement qu'en Java, une chaîne est entourée de guillemets doubles. C'est bien, mais le problème est qu'une ligne ne peut pas occuper plus d'une ligne du fichier source (pour éviter toute confusion avec une ligne Java, nous appellerons ici une ligne de fichier une « ligne »). Eh bien, faisons le tour et utilisons, par exemple, le symbole\n
si un saut est requis, ou une concaténation d'expressions multilignes. Cela ne se passe pas très bien ! Les littéraux de texte contenant des fragments HTML, XML, SQL ou JSON intégrés sont particulièrement fastidieux. Tous ces échappements, concaténation et édition manuelle rendent le code peu pratique à écrire et difficile à lire. Les blocs de texte tentent de résoudre ce problème. Ils commencent euh... par des guillemets triples et se terminent par eux (je sais, ça n'a pas l'air très bien). Tout ce qui se trouve entre les guillemets est interprété comme faisant partie de la ligne, y compris les nouvelles lignes. Les blocs de texte peuvent être utilisés exactement de la même manière que les littéraux de texte standard, et Java compilera le code de la même manière. Les guillemets d'ouverture doivent être suivis d'un délimiteur de ligne ; les blocs de texte ne peuvent pas être utilisés sur une seule ligne, donc le code
String smallBlock = """Only one line""";
entraînera les erreurs suivantes :
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block""";
^
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block""";
^
Un simple fragment HTML peut maintenant être écrit comme ceci :
String htmlBlock = """
<html>
<body>
<p>CodeGym Web page</p>
</body>
<html>
""";
Mentionnons quelques subtilités qu'il est préférable de connaître lors de l'utilisation de blocs de texte. L'emplacement des guillemets fermants s'avère important : il détermine la manière dont les espaces blancs occasionnels sont gérés. Dans l'exemple ci-dessus, les guillemets fermants sont alignés avec l'indentation du texte HTML. Dans ce cas, le compilateur supprimera les espaces d'indentation et nous obtiendrons par conséquent une ligne comme celle-ci :
<html>
<body>
<p>My web page</p>
</body>
</html>
Note:une telle ligne contiendra une nouvelle ligne à la fin de la ligne. Si cela n’est pas nécessaire, des guillemets fermants « » » peuvent être placés directement après la balise </html>. Si nous rapprochons les guillemets fermants de la marge de gauche, cela modifiera la quantité d’indentation supprimée. Si nous les déplacions de deux espaces vers la gauche, nous ajouterions deux espaces d'indentation à chaque ligne. En déplaçant vers le bord gauche, tout le remplissage sera préservé. Déplacer les guillemets plus à droite n’aura aucun effet et n’ajoutera plus d’indentation. Les blocs de texte ont été inclus dans JDK 13 en tant que fonctionnalité d'aperçu. Cela signifie qu'ils ne sont pas encore inclus dans la spécification du langage Java correspondante. Autrement dit, il n'est pas clair si cette fonctionnalité deviendra une partie permanente du langage ou si elle sera simplement un invité ici. Actuellement, les développeurs peuvent tester la fonctionnalité et donner leur avis là-dessus. Le sort des blocs de texte en dépendra : la fonctionnalité peut être améliorée, et si vous ne l'aimez pas, elle peut être complètement supprimée. Si vous souhaitez tester les blocs de texte en pratique, n'oubliez pas que les fonctionnalités d'aperçu doivent être explicitement incluses pour pouvoir être compilées et exécutées. Compilation:
javac --enable-preview --release 13 TextBlock.java
Pour exécuter l'application, vous devez activer les fonctionnalités d'aperçu :
java --enable-preview TextBlock
La classe String
dispose de trois nouvelles méthodes qui complètent ce changement de langage :
formatted()
: Formatez une chaîne en utilisant la chaîne elle-même comme chaîne de format. Equivalent d'un défiformat(this, args)
stripIndent()
: Supprime les espaces aléatoires d'une chaîne. Ceci est utile si vous lisez des chaînes multilignes et souhaitez appliquer la même exclusion d'espaces qu'avec une déclaration explicite.translateEscapes()
: renvoie une chaîne avec des séquences d'échappement (telles que\ r
), traduites en la valeur Unicode appropriée.
@PreviewFeature
aiderait dans de telles situations, mais elle n'est pas encore incluse dans le JDK (même si avec un degré de probabilité élevé, elle apparaîtra dans le JDK 14).
JEP 354 : Changer d'expression (aperçu)
Java 12 a introduit une proposition pour une nouvelle forme d'écriture d'expressions avec une instruction switch - JEP 325 . Il s’est avéré qu’il s’agissait de la toute première fonctionnalité en avant-première et son sort prouve que soumettre des propositions aux utilisateurs est une excellente idée. Avant le JDK 12,switch
il ne pouvait être utilisé que comme une instruction effectuant une action mais ne renvoyant pas de résultat. Mais dans Java 12, cela permettait de l'utiliser switch
comme une expression renvoyant un résultat pouvant être affecté à une variable. D'autres changements ont été apportés à la syntaxe des instructions case dans switch
. Regardons un exemple de JEP pour comprendre comment cela fonctionne.
int numberOfLetters;
switch(dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numberOfLetter = 6;
break;
case TUESDAY
numberOfLetter = 7;
break;
case THURSDAY
case SATURDAY
numberOfLetter = 8;
break;
case WEDNESDAY
numberOfLetter = 9;
break;
default:
throw new IllegalStateException("Huh?: " + day);
}
Dans cet exemple, nous utilisons value dayOfWeek
pour attribuer la valeur à numberOfLetters
. En raison des particularités du travail de l'opérateur switch
, ce code n'est pas le plus beau et il est facile de se tromper. Premièrement, si nous oublions d’appliquer une instruction break
à chaque groupe d’étiquettes de cas, nous utiliserons par défaut le groupe d’étiquettes de cas suivant. Cela peut conduire à des erreurs difficiles à trouver. Deuxièmement, nous devons définir chaque groupe d’étiquettes de cas. Si nous oublions, bien sûr, nous obtiendrons une erreur du compilateur, cependant, cette option n'est pas idéale. Notre code est également assez verbeux car chaque valeur dayOfWeek
doit avoir sa propre étiquette de cas. En utilisant la nouvelle syntaxe, nous obtenons un code beaucoup plus propre et moins sujet aux erreurs :
int numberOfLetters = switch (dayOfWeek) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
default -> throw new IllegalStateException("Huh?: " + day);
};
Désormais, nous n'avons besoin d'effectuer l'affectation qu'une seule fois (à partir de la switch
valeur de retour de l'expression) et pouvons utiliser une liste séparée par des virgules pour les étiquettes de cas. Et comme nous n'utilisons pas l'opérateur break
, nous éliminons les problèmes qui y sont associés. La syntaxe de l'expression switch
nous permet d'utiliser une syntaxe de style plus ancienne, donc dans JDK 12, nous pouvons l'écrire comme ceci :
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
break 6;
case TUESDAY
break 7;
case THURSDAY
case SATURDAY
break 8;
case WEDNESDAY
break 9;
default:
throw new IllegalStateException("Huh?: " + day);
};
Selon la communauté Java, utiliser la surcharge break
pour spécifier une valeur de retour peut prêter à confusion. Le langage Java vous permet également d'utiliser break
(et continue
) avec une étiquette comme l'opérateur de saut inconditionnel goto
. JEP 354 a modifié cette utilisation break
, donc dans Java 13, notre code change légèrement :
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
yield 6;
case TUESDAY
yield 7;
case THURSDAY
case SATURDAY
yield 8;
case WEDNESDAY
yield 9;
default:
throw new IllegalStateException("Huh?: " + day);
};
Les trois JEP suivantes sont associées à la machine virtuelle Java.
Archives CDS dynamiques JEP 350
Cette extension permet d'archiver dynamiquement des classes à la fin de l'exécution d'une application Java. CDS ou Class Data Sharing permet de regrouper toutes les classes lancées au démarrage dans une archive spécialeclass data sharing
, en utilisant la liste de ces mêmes classes par défaut. Cela conduit à une accélération significative du lancement des applications et de l'économie de RAM. Auparavant, l'utilisation d'AppCDS était un processus en plusieurs étapes qui impliquait la création d'une liste de classes pertinentes et l'utilisation de cette liste pour créer une archive qui serait utilisée pour les exécutions ultérieures. Il ne reste plus qu'à lancer l'application avec le drapeau -XX: ArchiveClassesAtExit
indiquant l'emplacement où l'archive sera écrite. Avec cette approche, les classes sont automatiquement regroupées dans une archive après l'arrêt normal de l'application.
JEP 351 ZGC : Libérer la mémoire inutilisée
Il y a un an, JDK 11 introduisait ZGC, un garbage collector expérimental, évolutif et à faible latence. Au début, ZGC s'est comporté assez étrangement : il ne permettait pas de restituer la mémoire au système d'exploitation, même si elle n'était plus nécessaire. Pour certains environnements, tels que les conteneurs, où les ressources sont utilisées par plusieurs services en même temps, cela peut limiter l'évolutivité et l'efficacité du système. Le tas ZGC est constitué de ce qu'on appelle des ZPages. Lorsque les ZPages sont effacées pendant le cycle de garbage collection, elles sont renvoyées au ZPageCache. Les ZPages de ce cache sont classées selon leur date d'utilisation récente. Dans Java 13, ZGC renverra au système d'exploitation les pages identifiées comme n'étant pas utilisées depuis longtemps. De cette façon, ils peuvent être réutilisés pour d’autres processus.JEP 353 Réimplémenter l'ancienne API Socket
Les deux implémentations d'APIjava.net.Socket
sont java.net.ServerSocket
toujours JDK 1.0. Dans ce JDK, ainsi que dans tous les JDK ultérieurs, l'implémentation de ces API utilise plusieurs techniques (telles que l'utilisation de la pile de threads comme tampon d'E/S) qui les rendent rigides et difficiles à maintenir. Pour résoudre ce problème, une nouvelle implémentation a été fournie dans le JDK 13 NioSocketImpl
. Il ne nécessite plus de code natif, ce qui facilite le portage sur différentes plateformes. Cette classe utilise également le mécanisme de cache de tampon existant (évitant l'utilisation de la pile de threads à cette fin) et java.util.concurrent
des méthodes de verrouillage plutôt que synchronisées. Cela simplifiera l'intégration avec les fibres du Project Loom .
Nouvelles API
Nous avons mentionné précédemment que Java 13 inclut 76 nouvelles API dans les bibliothèques de classes de base. Ils couvrent les domaines suivants :- Mises à jour de prise en charge Unicode.
- Trois nouvelles méthodes
String
pour prendre en charge les blocs de texte (voir la description JEP 255 ci-dessus). - Les classes
java.nio
ont désormais des valeurs absolues (par opposition à relatives)get
etdéfinir des méthodes. Comme la classe abstraite de base, elles Buffer
incluent une méthodeslice()
pour récupérer une partie du tampon. - La méthode
force()
de classeMappedByteBuffer
force l'écriture d'une section tampon dans son stockage de sauvegarde. nio.FileSystem
ajoute trois nouveaux formulaires surchargésnewFileSystem()
pour accéder au contenu d'un fichier en tant que système de fichiers.- Une nouvelle méthode intéressante est
javax.annotation.processing.ProcessingEnvironment
apparue.isPreviewEnabled()
. Il vous dira si les fonctionnalités d'aperçu sont activées. Ceci est intéressant car l'annotation mentionnée ci-dessus@PreviewFeature
ne sera pas disponible avant la sortie du JDK 14. DocumentBuilderFactory
etSAXParserFactory
bénéficiezjavax.xml.parsers
de trois nouvelles méthodes pour créer des instances prenant en charge les espaces de noms.
GO TO FULL VERSION