web-dev-qa-db-fra.com

Quelle est la différence entre requiert et requiert des instructions transitives dans Java 9?

Quelle est la différence entrerequiertetrequiert des instructions transitivesmodule dans la déclaration de module?

Par exemple:

module foo {
    requires Java.base;
    requires transitive Java.compiler;
}
39
Michał Szewczyk

Récapitulation lisibilité

Si module barrequires module boire _, le système de module ...

  • impose la présence de boisson (appelée configuration fiable)
  • permet à barre de lire boire (appelé lisibilité )
  • permet au code dans bar d'accéder aux classes publiques des packages exportés dans boire (appelé accessibilité )

Il en va exactement de même si barrerequires transitive drink - boisson doit être présent, lisible et accessible. En fait, pour bar _ et boire, le mot clé transitive ne change rien.

Lisibilité implicite

Les modules dépendants de bar sont ceux affectés par transitive: Tout module qui lit bar peut également lire boire. En d’autres termes, la lisibilité de boire est implicite (c’est pourquoi on l’appelle lisibilité implicite ). Une conséquence est que (client} _ peut accéder aux types de boire.

Donc, si bar requires transitive drink et customer requires bar, alors client peut lire boire même si cela n'en dépend pas explicitement.

Cas d'utilisation

Mais pourquoi? Imaginez que vous ayez un module dont l'API publique accepte ou retourne le type d'un autre module. Supposons que le module bar renvoie publiquement des instances de Drink, une interface du module drink:

// in module _bar_
public class Bar {

    // `Drink` comes from the module _drink_,
    // which _bar_ requires
    public Drink buyDrink() { /* ... */ }

}

Dans cet exemple, bar utilise une constante requires pour boire. Maintenant, disons que client dépend de bar, de sorte que tout son code peut appeler Bar::buyDrink. Mais que se passe-t-il quand cela se produit?

Le système de module se plaint que client ne lit pas boit et ne peut donc pas accéder à Drink. Pour résoudre ce problème, client devrait également dépendre de boire. Quelle corvée! Combien inutile est un bar que vous ne pouvez pas utiliser tout de suite?

 customer requires bar requires drink - but how does customer read drink?

Pour cette raison, la lisibilité implicite a été introduite: pour rendre un module qui utilise les types d’un autre module dans sa propre API publique immédiatement utilisable sans obligeant l’appelant à rechercher et à exiger tous les modules impliqués.

Donc, si bar requires transitive drink, client peut commencer à acheter des boissons sans avoir à require drink - require bar suffire. Comme il se doit.

51
Nicolai

La principale différence entre les deux est l'accès d'un module dépendant d'un module à un autre.

Si un module exporte un package contenant un type dont la signature fait référence à un paquet dans un second module puis à la déclaration du Le premier module devrait inclure une dépendance requires transitive sur la deuxième. Cecifera en sorte que les autres modules qui dépendent du le premier module sera automatiquement capable de lire le second moduleet, accédez donc à tous les types des packages exportés de ce module.


Alors disons pour votre cas d'utilisation: -

module foo {
    requires Java.base;
    requires transitive Java.compiler;
}

~> Tout module dépendant du module foo lira automatiquement le module Java.compiler 

~> D'autre part, pour accéder au module Java.base, ils doivent spécifier à nouveau une clause requires.

module bar {
    requires foo; // Java.compiler is available to read
    requires Java.base; // still required
}
6
nullpointer

requires décrit le processus de résolution de la dépendance des modules. 

Ligne de citation 

(Une directive 'requiert' (indépendamment de 'transitive') indique que Un module dépend d'un autre module. L'effet du le modificateur 'transitif' doit faire en sorte que des modules supplémentaires dépendent également de l'autre module. Si le module M 'nécessite un transitif N', alors pas seulement M dépend-il de N, mais tout module dépendant de M dépend également de N. Cela permet à M d’être refactorisé de sorte que tout ou partie de son contenu peut être déplacé vers un nouveau module N sans casser les modules qui ont un 'nécessite M' directive.

En bref :

requires - Le module M dépend d'un autre module N.

requires transitive - les modules supplémentaires dépendent implicitement de l'autre module. Par exemple, si M module dépend de N et que l'autre module P dépend de M. Il dépend alors implicitement de N. 

5
Ravi

Nicolai a expliqué en détail. Je donne juste un exemple spécifique du code JDK ici. Considérons le module jdk.scripting.nashorn. Le module-info de ce module est le suivant:

http://hg.openjdk.Java.net/jdk9/dev/nashorn/file/17cc754c8936/src/jdk.scripting.nashorn/share/classes/module-info.Java

Il a cette ligne:

requires transitive Java.scripting;

Ceci est dû au fait que jdk.scripting.nashorn propre API du module dans jdk.scripting.api.scripting package accepte/renvoie les types de javax.script package du Java.scripting module. Ainsi, jdk.scripting.nashorn indique à JMPS que tout module dépendant de jdk.scripting.nashorn dépend automatiquement du module Java.scripting!

Maintenant, le même module jdk.scripting.nashorn utilise cette ligne:

    requires jdk.dynalink;

pour un autre module jdk.dynalink . En effet, none des packages exportés ("API") du module jdk.scripting.nashorn utilise les types du module jdk.dynalink. L'utilisation de jdk.dynalink par jdk.scripting.nashorn est purement un détail d'implémentation. 

2
A. Sundararajan

La spécification du langage Java pour Java 9 l'explique en termes très simples. Dans la section Dépendances des modules :

La directive requires spécifie le nom d'un module sur lequel le module actuel a une dépendance.

...

Le mot clé requires peut être suivi du modificateur transitive. Ceci fait que tout module dont le paramètre requires du module actuel a une dépendance implicite déclarée par rapport au module spécifié par la directive requires transitive

En d'autres termes:

  • si module X requires module Y,
  • et module Y requires transitive module Z,
  • puis module X également (implicitement) requires module Z.
1
manouti

Le terme accessibility est ambigu: vous pouvez accéder à des objets sans accéder à leur type. Si un objet de type T réside dans un package non exporté et si un code "exporté" a une méthode qui renvoie un T ... Ensuite, lors de l'appel de cette méthode, vous obtenez un descripteur sur cet objet invoquer dessus toutes les méthodes qui appartiennent à tout type connu de votre code).

readability est également ambigu: cela ne signifie pas que votre ClassLoader sera toujours incapable de charger la classe T (non exportée).

0
bear