Nouveaux mots clés dans Java 9
L'une des plus grandes fonctionnalités de Java 9 sera un système de modules défini par Project Jigsaw. Lors de la lecture des diapositives du projet Jigsaw: Under The Hood à JavaOne 2015, j'ai remarqué le code source suivant:
// src/java.sql/module-info.java
module java.sql {
exports java.sql;
exports javax.sql;
exports javax.transaction.xa;
}
Ce qui m'intéresse ici, c'est que le fichier se termine par .java
et semble utiliser deux nouveaux mots-clés: module
, et exports
. Quels autres mots-clés seront introduits dans Java 9? Comment la rétrocompatibilité sera-t-elle traitée (c'est-à-dire des fonctions ou des variables nommées module
)?
4 réponses
Les mots-clés ajoutés pour les déclarations de module dans Java 9 sont résumés dans §3.9 de la spécification du langage Java , Java SE 9 Édition :
Dix autres séquences de caractères sont des mots clés restreints:
open
,module
,requires
,transitive
,exports
,opens
,to
,uses
,provides
, etwith
. Ces séquences de caractères sont tokenisées comme mots clés uniquement lorsqu'ils apparaissent comme des terminaux dans le ModuleDeclaration et moduledirective productions (§7.7). Ils sont segmentées comme identificateurs partout ailleurs, pour la compatibilité avec les programmes écrits avant Java SE 9. Il y a une exception: immédiatement à droite de la séquence de caractères nécessite dans le Moduleproduction directive, la séquence de caractères transitive est tokenisée en tant que mot clé à moins qu'elle est suivi d'un séparateur, auquel cas il est tokenisé comme identificateur.
Si vous avez actuellement une méthode nommée module
, ou l'une de l'autre
mots-clés listés ici continuer à compiler.
(view
et permits
étaient des mots-clés dans un premier prototype de puzzle, mais
ils ont été simplifiés hors de l'existence il y a longtemps.)
Ce n'est probablement pas une liste complète, et rien de cela n'a été finalisé au meilleur de ma connaissance, mais je l'ai trouvé un peu.
Nous avons aussi module
, exports
, provides
, uses
, with
, to
, et requires
; expliqué ici:
Le système de module pourrait identifier les utilisations des services en analysant les fichiers de classe dans les artefacts de module pour les invocations des méthodes ServiceLoader:: load, mais cela serait à la fois lent et peu fiable. Un module utilise un service en particulier est un aspect fondamental de la définition de ce module, donc pour l'efficacité et la clarté, nous exprimons que dans la déclaration du module avec une clause uses:
module java.sql { requires public java.logging; requires public java.xml; exports java.sql; exports javax.sql; exports javax.transaction.xa; uses java.sql.Driver; }
Le système de module pourrait identifier les fournisseurs de services en scannant les artefacts de module pour les entrées de ressources META-INF / services, comme le fait Aujourd'hui la classe ServiceLoader. Qu'un module fournit une implémentation d'un service particulier est tout aussi fondamental, cependant, nous exprimons donc que dans la déclaration du module avec A fournit clause:
module com.mysql.jdbc { requires java.sql; requires org.slf4j; exports com.mysql.jdbc; provides java.sql.Driver with com.mysql.jdbc.Driver; }
...
module java.base { ... exports sun.reflect to java.corba, java.logging, java.sql, java.sql.rowset, jdk.scripting.nashorn; }
Aussi view
et permits
:
Dans de grands systèmes logiciels, il est souvent utile de définir plusieurs vues d'un même module. Une vue peut être déclarée pour une utilisation générale par n'importe quel autre module, tandis qu'une autre donne accès à des interfaces internes destinées uniquement à être utilisées par un ensemble de modules étroitement liés.
Par exemple avec JNDI nous voulons que com.soleil.jndi.Toolkit.url être visible uniquement pour cosnaming et modules kerberos, comme spécifié dans la déclaration du module.
view jdk.jndi.internal { exports com.sun.jndi.toolkit.url.*; exports sun.net.dns.*; permits jdk.cosnaming; permits jdk.kerberos;
}
De cette façon, nous avons plus de flexibilité pour définir les limites des modules.
J'ai aussi entendu parler de optional
.
Moduleest un nouveaux clé introduite pour définir les interdépendances entre les paquets. Pourquoi avons-nous besoin de modules? Parce que plus tôt
- , l'encapsulation n'était pas immaculée. Avec l'aide de la réflexion et avec des techniques similaires, nous avons pu accéder même au domaine privé.
- Toutes les classes dans tous les pots étaient accessibles au public.
-
Si le Classloader n'obtient pas la classe, il devait regarder dans beaucoup de zones et charger beaucoup de fichiers associés et même après cela, si la classe n'est pas trouvée, elle lancerait NoClassDefFoundErrors au moment de l'exécution.
Donc, pour toutes les raisons ci-dessus, nous avons besoin d'un mécanisme qui permet à JVM de le savoir lors de l'exécution. Pour implémenter le module, vous devez définir
module-info.java
. dans ce paquetmodule com.exporter{ exports com.a; provides com.b.M; with com.b.MImpl; }
Dans un autre paquet,
module com.consume {
requires com.a;
}
Autres attributs utilisés sont "exportations" et "requiert" pour faire une inter dépendance(dépendance transitive seulement), "donne" et " avec " pour exposer l'interface et mentionner l'implémentation. Donc, c'est une forte encapsulation, peut-être, c'est pourquoi java 9 est plus enclin à une meilleure fonctionnalité orientée objet.
Pour la partie rétrocompatibilité de la question.
Je pense que JAVA9 / project jigsaw est un changement de paradigme dans la technologie Java. de sorte que java9 ne sera pas rétrocompatible, mais vous pouvez facilement transformer votre dépendance non modulaire avec la version modulaire de la même bibliothèque. le concept de "sans douleur, sans Gain" fonctionnera ici. Tout le monde doit mettre à niveau/transformer pour profiter de la nouvelle java modulaire. Développeur IDE, développeur de plugins, système de construction et bien sûr niveau groud java développeur besoin de comprendre les nouveaux systèmes java.
JAVA9 préconise une dépendance propre. il fournit également une toute nouvelle façon de sécuriser votre code par des modules privés. même reflection ne peut pas accéder aux modules non exposés par le propriétaire de la bibliothèque/API.
Il existe deux approches pour utiliser des LIB / API non modulaires.
- approche descendante
- approche ascendante (beaucoup de douleur ici à mettre en œuvre)
La deuxième approche crée une hiérarchie de dépendances de module très propre.