it-swarm.com.de

Was ist der Unterschied zwischen erforderlichen und erforderlichen transitiven Anweisungen in Java 9?

Was ist der Unterschied zwischenerfordertunderfordert transitiveModulanweisungen in der Moduldeklaration?

Zum Beispiel:

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

Ablesbarkeit rekapitulieren

Wenn module barrequires module drink, dann ist das Modulsystem ...

  • erzwingt das Vorhandensein von trinken ( zuverlässige Konfiguration)
  • erlaubt Bar zu lesen Drink (genannt Lesbarkeit )
  • ermöglicht Code in bar den Zugriff auf öffentliche Klassen in exportierten Paketen in drink (genannt accessibility )

Genau das gleiche passiert, wenn barrequires transitive drink - drink muss vorhanden sein, kann gelesen und abgerufen werden. Tatsächlich ändert das Schlüsselwort transitive für bar und drink nichts.

Implizite Lesbarkeit

Die Module sind abhängig von Balken diejenigen, die von transitive betroffen sind: Jedes Modul, das liest bar kann auch lesen trinken. Mit anderen Worten, die Lesbarkeit von drink ist impliziert (weshalb dies implizite Lesbarkeit ). Eine Konsequenz ist, dass Kunde auf Getränk Typen zugreifen kann.

Also, wenn bar requires transitive drink und customer requires bar, dann kann Kunde lesen trinken obwohl es nicht explizit davon abhängt.

Anwendungsfälle

Aber wieso? Stellen Sie sich vor, Sie haben ein Modul, dessen öffentliche API den Typ eines anderen Moduls akzeptiert oder zurückgibt. Angenommen, das Modul bar gibt öffentlich Instanzen von Drink zurück, einer Schnittstelle aus dem Modul drink:

// in module _bar_
public class Bar {

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

}

In diesem Beispiel verwendet bar ein reguläres requires für drink. Sagen Sie nun, Kunde hängt von Bar ab, damit der gesamte Code Bar::buyDrink. Aber was passiert dann?

Das Modulsystem beanstandet, dass Kunde nicht Getränk liest und daher nicht auf Drink zugreifen kann. Um das zu beheben, müsste Kunde auch von Getränk abhängen. Was für eine lästige Pflicht! Wie nutzlos ist ein Riegel, den man nicht gleich benutzen kann?

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

Aus diesem Grund wurde die implizite Lesbarkeit eingeführt: Um ein Modul, das die Typen eines anderen Moduls in seiner eigenen öffentlichen API verwendet, sofort nutzbar zu machen, ohne muss der Aufrufer suchen und alle beteiligten Module anfordern.

Also, wenn bar requires transitive drink, Kunde kann Getränke kaufen, ohne require drink - require bar reicht aus. So wie es sollte.

69
Nicolai

Der Hauptunterschied zwischen den beiden ist der Zugriff eines abhängigen Moduls von einem zum anderen.

Wenn ein Modul ein Paket exportiert, das einen Typ enthält, dessen Signatur bezieht sich auf ein Paket in einem zweiten Modul dann die Deklaration der Das erste Modul sollte eine requires transitive-Abhängigkeit von .__ enthalten. der Zweite. Diesestellt sicher, dass andere Module, die von der .__ abhängig sind. Das erste Modul kann das zweite Modulund, .__ automatisch lesen. Greifen Sie daher auf alle Typen in den exportierten Paketen dieses Moduls zu.


Sagen wir also für Ihren Anwendungsfall: -

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

~> Jedes Modul, das auf das foo-Modul angewiesen ist, liest automatisch das Java.compiler-Modul 

~> Um auf das Modul Java.base zuzugreifen, müssen sie jedoch erneut eine requires-Klausel angeben.

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

requires beschreibt den Prozess der Auflösung, in der die Module voneinander abhängig sind. 

Notierungszeile 

Eine 'Direktive'-Direktive (unabhängig von' transitiv ') drückt aus, dass Ein Modul von einem anderen Modul abhängt. Die Wirkung von 'Transitiv'-Modifizierer bewirkt, dass zusätzliche Module auch von dem anderen Modul abhängen. Wenn das Modul M 'ein transitives N' erfordert, dann nicht nur hängt M von N ab, aber jedes Modul, das von M abhängig ist, hängt auch von .__ ab. N. Dadurch kann M so umgestaltet werden, dass ein Teil des Inhalts oder der gesamte Inhalt kann zu einem neuen Modul N verschoben werden, ohne dass Module mit einem .__ unterbrochen werden. 'erfordert M'-Direktive.

Zusamenfassend :

requires - Das M-Modul hängt von einem anderen Modul N ab.

requires transitive - zusätzliche Module hängen implizit vom anderen Modul ab. Beispiel :, Wenn das Modul M von N abhängt und das andere Modul P von M abhängt. Dann ist es auch implizit von N abhängig. 

5
Ravi

Nicolai hat es ausführlich erklärt. Ich gebe hier nur ein konkretes Beispiel aus dem JDK-Code. Betrachten Sie das Modul jdk.scripting.nashorn. Die Modulinformationen dieses Moduls lauten wie folgt:

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

Es hat diese Zeile:

requires transitive Java.scripting;

Dies liegt daran, dass jdk.scripting.nashorn moduls eigene API in jdk.scripting.api.scripting package akzeptiert/zurückgibt Typen von javax.script package der Java.scripting Modul. Daher teilt jdk.scripting.nashorn dem JMPS mit, dass jedes Modul, das von jdk.scripting.nashorn abhängt, automatisch auch vom Java.scripting-Modul abhängt!

Jetzt verwendet dasselbe Modul jdk.scripting.nashorn diese Zeile:

    requires jdk.dynalink;

für ein anderes Modul jdk.dynalink . Das liegt daran, dass none der exportierten Pakete (die "API") aus dem Modul jdk.scripting.nashorn Typen aus dem Modul jdk.dynalink verwendet. Die Verwendung von jdk.dynalink von jdk.scripting.nashorn ist ein reines Implementierungsdetail. 

2
A. Sundararajan

Die Java-Sprachspezifikation für Java 9 erklärt es sehr einfach. Aus dem Abschnitt Modulabhängigkeiten :

Die Direktive requires gibt den Namen eines Moduls an, von dem das aktuelle Modul abhängig ist.

...

Auf das Schlüsselwort requires kann der Modifikator transitive folgen. Dies bewirkt, dass jedes Modul, das das aktuelle Modul requires ist, eine implizite Abhängigkeit von dem in der requires transitive-Direktive angegebenen Modul hat.

Mit anderen Worten:

  • wenn Modul X requires Modul Y,
  • und Modul Y requires transitive Modul Z,
  • dann Modul X auch (implizit) requires Modul Z.
1
manouti

Der Begriff accessibility ist mehrdeutig: Sie können auf Objekte ohne Zugriff auf ihren Typ zugreifen. Wenn ein Objekt vom Typ T ist, das in einem Paket liegt, das nicht exportiert wird, und wenn ein "exportierter" Code über eine Methode verfügt, die ein T zurückgibt ... Wenn Sie diese Methode aufrufen, erhalten Sie ein Handle für dieses T-Objekt (und Sie können dies tun) Rufen Sie alle Methoden auf, die sich auf jeden Typ beziehen, der Ihrem Code bekannt ist.

Lesbarkeit ist auch nicht eindeutig: Dies bedeutet nicht, dass Ihr ClassLoader die (nicht exportierte) T-Klasse immer laden kann.

0
bear