requiresとrequiretiveモジュール宣言のモジュール文?
例えば:
module foo {
requires Java.base;
requires transitive Java.compiler;
}
モジュールbarrequires
moduledrinkの場合、モジュールシステム...
barrequires transitive drink
-drinkが存在する必要があり、読み取りとアクセスが可能な場合、まったく同じことが起こります。実際、barおよびdrinkの場合、transitive
キーワードは何も変更しません。
モジュールbarに依存するtransitive
の影響を受けるモジュール:barを読み取るモジュールは、drinkも読み取ることができます。 drinkis implied(これが impeded readability )と呼ばれる理由です。結果はcustomerにアクセスできますdrinkのタイプ。
したがって、bar requires transitive drink
およびcustomer requires bar
の場合、明示的に依存していなくても、customerはdrinkを読み取ることができます。
しかし、なぜ?パブリックAPIが別のモジュールのタイプを受け入れるまたは返すモジュールがあるとします。 barモジュールがdrinkモジュールからのインターフェースであるDrink
のインスタンスをパブリックに返すとしましょう:
// in module _bar_
public class Bar {
// `Drink` comes from the module _drink_,
// which _bar_ requires
public Drink buyDrink() { /* ... */ }
}
この例では、barはdrinkに通常のrequires
を使用します。 customerはbarに依存しているため、すべてのコードがBar::buyDrink
を呼び出すことができます。しかし、そうなるとどうなりますか?
モジュールシステムはcustomerがdrinkを読み取らないため、Drink
にアクセスできないと文句を言います。これを修正するには、customerもdrinkに依存する必要があります。なんてつまらない!すぐに使用できないバーはどれほど役に立たないでしょうか?
このため、暗黙の読み取り可能性が導入されました:独自のパブリックAPIで別のモジュールのタイプを使用するモジュールをすぐに使用できるようにするなし呼び出し元にすべての関連モジュールを追い詰めて要求する必要があります。
したがって、bar requires transitive drink
、customerは、require drink
-require bar
で十分でなくても、飲み物の購入を開始できます。あるべきです。
2つの主な違いは、依存モジュールの一方から他方へのアクセスです。
1つのモジュールが、2番目のモジュールのパッケージを参照する署名を持つ型を含むパッケージをエクスポートする場合、最初のモジュールの宣言には、2番目のモジュールへの
requires transitive
依存関係が含まれます。このは、最初のモジュールに依存する他のモジュールが自動的に2番目のモジュールを読み取ることができるようにしますしたがって、そのモジュールのエクスポートされたパッケージ内のすべてのタイプにアクセスします。
それでは、ユースケースについて言ってみましょう:-
module foo {
requires Java.base;
requires transitive Java.compiler;
}
〜> foo
モジュールに依存するモジュールは、自動的にJava.compiler
モジュールを読み取ります
〜>一方、モジュールJava.base
にアクセスするには、requires
句を再度指定する必要があります。
module bar {
requires foo; // Java.compiler is available to read
requires Java.base; // still required
}
requires
は、モジュールが相互に依存する方法に関する解決のプロセスを説明します。
「requires」ディレクティブ(「transitive」に関係なく)は、1つのモジュールが他のモジュールに依存することを表します。 'transitive'修飾子の効果は、追加モジュールが他のモジュールにも依存するようにすることです。モジュールMが推移的Nを必要とする場合、MはNに依存するだけでなく、Mに依存するモジュールもNに依存します。これにより、Mのリファクタリングが可能になり、コンテンツの一部またはすべてを新しい「requires M」ディレクティブを持つモジュールを壊さずにモジュールN。
要するに :
requires
-Mモジュールは他のモジュールNに依存します。
requires transitive
-追加モジュールは暗黙的に他のモジュールに依存します。たとえば、MモジュールがNに依存し、他のモジュールPがMに依存している場合、暗黙的にNにも依存します。
ニコライは詳細に説明しました。ここでは、JDKコードの特定の例を示しています。 jdk.scripting.nashornモジュールを検討してください。このモジュールのモジュール情報は次のとおりです。
次の行があります。
requires transitive Java.scripting;
これは、- jdk.scripting.nashornjdk.scripting.api.scripting パッケージの独自のAPIが javax.script packageから型を受け入れる/返すためです。 Java.scripting モジュールの。したがって、jdk.scripting.nashornはJMPSに、jdk.scripting.nashornに依存するモジュールはすべて自動的にJava.scriptingモジュールにも依存することを伝えます!
現在、同じjdk.scripting.nashornモジュールは次の行を使用しています。
requires jdk.dynalink;
別のモジュールの場合 jdk.dynalink 。これは、jdk.scripting.nashornモジュールからエクスポートされたパッケージ(「API」)のnoneがjdk.dynalinkモジュールの型を使用するためです。 jdk.scripting.nashornによるjdk.dynalinkの使用は、純粋に実装の詳細です。
Java Java 9の言語仕様は、非常に簡単な用語で説明しています。 Module Dependences のセクションから:
requires
ディレクティブは、現在のモジュールが依存しているモジュールの名前を指定します。...
requires
キーワードの後に修飾子transitive
を続けることができます。 これにより、現在のモジュールをrequires
するモジュールが、requires transitive
ディレクティブで指定されたモジュールに暗黙的に宣言された依存関係を持つようになります。
言い換えると:
requires
モジュールYの場合、requires transitive
モジュールZ、requires
モジュールZも。accessibilityという用語はあいまいです。タイプにアクセスせずにオブジェクトにアクセスできます。オブジェクトがエクスポートされていないパッケージにあるタイプTであり、「エクスポートされた」コードにTを返すメソッドがある場合...このメソッドを呼び出すと、このTオブジェクトのハンドルが取得されます(そして、コードで既知の型に関連するメソッドを呼び出します)。
読みやすさも曖昧です:ClassLoaderが常に(エクスポートされていない)Tクラスをロードできないという意味ではありません。