Quelle est la différence entre requires et requires transitive statements dans Java 9?

Quelle est la différence entre nécessite et nécessite transitif module énoncés dans la déclaration de module?

Par exemple:

module foo {
    requires java.base;
    requires transitive java.compiler;
}
32
demandé sur nullpointer 2017-09-30 14:53:56

6 réponses

Récapitulation de la lisibilité

Si le module bar requires module boisson, alors le système de module...

  • applique la présence de boisson (appelé fiable de configuration)
  • permet de bar lire boisson (appelé la lisibilité)
  • permet au code dans bar {[18] } d'accéder aux classes publiques dans les paquets exportés dans drink (appelé l'accessibilité)

Exactement la même chose arrive si bar requires transitive drink - boire doit être présent, peut être lu et consulté. En fait, pour bar et boisson le transitive clé ne change rien.

Lisibilité implicite

Les modules selon bar sont ceux qui sont touchés par transitive: un module qui lit bar pouvez également lire les boisson. En d'autres termes la lisibilité de boisson est implicite (qui est pourquoi ce qui est appelé implicite de lisibilité). Une conséquence est que customer peut accéder aux types de drink.

Si bar requires transitive drink et customer requires bar, puis clients pouvez lire boisson, même si elle ne prend pas explicitement en dépendent.

Cas d'Utilisation

, Mais pourquoi? Imaginez que vous avez un module dont L'API publique accepte ou renvoie le type d'un autre module. Disons que l' bar module publiquement retourne les instances de Drink, une interface à partir de la boisson module:

// in module _bar_
public class Bar {

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

}

Dans cet exemple, bar utilise régulièrement requires pour boisson. Maintenant dire, clients dépend de bar, de sorte que tous ses code peut appeler Bar::buyDrink. Mais ce qui arrive quand il le fait?

Le système de module se plaint que client {[18] } ne lit pas boisson et ne peut donc pas accéder à Drink. Pour résoudre ce problème, client serait doivent également dépendre de boire . Quelle corvée! Comment inutile est une barre que vous ne pouvez pas utiliser tout de suite?

le client l'exige bar implique boire - mais comment le client lire la boisson?

Pour cette raison, la lisibilité implicite a été introduite: rendre un module qui utilise les types d'un autre module dans sa propre API publique instantanément utilisable sans obliger l'appelant à traquer et à exiger tous les modules impliqués.

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

42
répondu Nicolai 2018-09-09 09:07:31

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

Si un module exporte un paquet 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 deuxième. Ceci veillera à ce que d'autres modules qui dépendent de la premier module sera automatiquement en mesure de lire le deuxième module et, par conséquent, l'accès de tous les types dans les paquets exportés de ce module.


Disons donc pour votre cas d'utilisation: -

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

~ > tout module qui dépend du module foo lira automatiquement le module java.compiler

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

module bar {
    requires foo; // java.compiler is available to read
    requires java.base; // still required
}
6
répondu nullpointer 2017-10-01 07:00:54

requires décrit le processus de résolution sur la façon dont les modules dépendent les uns des autres.

Ligne de citation

une directive "exige" (indépendamment de "transitive") exprime que un module dépend d'un autre module. L'effet de la 'le modificateur transitif est de faire dépendre également des modules supplémentaires l'autre module. Si le module M 'nécessite transitive N', alors non seulement M dépend-il de N, mais un module qui dépend de M dépend aussi 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 'exige m' directive.

En bref :

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

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

5
répondu Ravi 2017-09-30 15:36:21

Nicolai a expliqué en détail. Je donne juste un exemple spécifique du code JDK ici. Considérez le jdk.l'écriture de scripts.module 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;

C'est parce que jdk.l'écriture de scripts.Nashorn propre API du module dans jdk.l'écriture de scripts.API.script Paquet accepte / renvoie les types de javax.script paquet du java.script module. Alors jdk.l'écriture de scripts.nashorn dit au JMPS que tout module qui dépend de jdk.l'écriture de scripts.nashorn dépend automatiquement de java.module de script aussi bien!

Maintenant, le même jdk.l'écriture de scripts.le module nashorn utilise cette ligne:

    requires jdk.dynalink;

Pour un autre module jdk.dynalink . C'est parce que aucun des paquets exportés (l ' "API") de jdk.l'écriture de scripts.le module Nashorn utilise des types à partir du jdk.module dynalink. L'utilisation de jdk.dynalink par jdk.l'écriture de scripts.nashorn est purement un détail de mise en œuvre.

2
répondu A. Sundararajan 2017-09-30 16:01:38

La spécification du langage Java pour Java 9 l'explique en termes très simples. De la section sur dépendances du Module :

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. cela provoque tout module qui requires le module actuel d'avoir une dépendance implicitement déclarée sur le module spécifié par le requires transitive directive.

En d'autres termes:

  • si le module X requires module Y,
  • et module y requires transitive module Z,
  • puis module X aussi (implicitement) requires module Z.
1
répondu manouti 2017-09-30 18:14:00

Le terme accessibilité est ambigu: vous pouvez accéder aux objets sans accéder à leur type. Si un objet est de type T qui se trouve dans un package qui n'est pas exporté et si un code "exporté" a une méthode qui renvoie un T... Ensuite, lorsque vous invoquez cette méthode, vous obtenez un handle sur cet objet T (et vous pouvez y invoquer toutes les méthodes qui se rapportent à n'importe quel type connu de votre code).

la lisibilité est également ambiguë: cela ne signifie pas que votre ClassLoader sera toujours incapable de charger le (désexporter) T de la classe.

0
répondu bear 2018-02-14 11:10:32