web-dev-qa-db-ja.com

Java 9のrequireステートメントとrequire推移的ステートメントの違いは何ですか?

requiresrequiretiveモジュール宣言のモジュール文?

例えば:

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

読みやすさのまとめ

モジュールbarrequires moduledrinkの場合、モジュールシステム...

  • drink信頼できる構成と呼ばれる)の存在を強制します
  • barの読み取りを許可drink(呼び出された readability
  • barのコードがdrinkaccessibility と呼ばれる)のエクスポートされたパッケージのパブリッククラスにアクセスできるようにします

barrequires transitive drink-drinkが存在する必要があり、読み取りとアクセスが可能な場合、まったく同じことが起こります。実際、​​barおよびdrinkの場合、transitiveキーワードは何も変更しません。

暗黙の読みやすさ

モジュールbarに依存するtransitiveの影響を受けるモジュール:barを読み取るモジュールは、drinkも読み取ることができます。 drinkis implied(これが impeded readability )と呼ばれる理由です。結果はcustomerにアクセスできますdrinkのタイプ。

したがって、bar requires transitive drinkおよびcustomer requires barの場合、明示的に依存していなくても、customerdrinkを読み取ることができます。

ユースケース

しかし、なぜ?パブリックAPIが別のモジュールのタイプを受け入れるまたは返すモジュールがあるとします。 barモジュールがdrinkモジュールからのインターフェースであるDrinkのインスタンスをパブリックに返すとしましょう:

// in module _bar_
public class Bar {

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

}

この例では、bardrinkに通常のrequiresを使用します。 customerbarに依存しているため、すべてのコードがBar::buyDrinkを呼び出すことができます。しかし、そうなるとどうなりますか?

モジュールシステムはcustomerdrinkを読み取らないため、Drinkにアクセスできないと文句を言います。これを修正するには、customerdrinkに依存する必要があります。なんてつまらない!すぐに使用できないバーはどれほど役に立たないでしょうか?

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

このため、暗黙の読み取り可能性が導入されました:独自のパブリックAPIで別のモジュールのタイプを使用するモジュールをすぐに使用できるようにするなし呼び出し元にすべての関連モジュールを追い詰めて要求する必要があります。

したがって、bar requires transitive drinkcustomerは、require drink-require barで十分でなくても、飲み物の購入を開始できます。あるべきです。

69
Nicolai

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
}
6
Naman

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にも依存します。

5
Ravi

ニコライは詳細に説明しました。ここでは、JDKコードの特定の例を示しています。 jdk.scripting.nashornモジュールを検討してください。このモジュールのモジュール情報は次のとおりです。

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

次の行があります。

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の使用は、純粋に実装の詳細です。

2
A. Sundararajan

Java Java 9の言語仕様は、非常に簡単な用語で説明しています。 Module Dependences のセクションから:

requiresディレクティブは、現在のモジュールが依存しているモジュールの名前を指定します。

...

requiresキーワードの後に​​修飾子transitiveを続けることができます。 これにより、現在のモジュールをrequiresするモジュールが、requires transitiveディレクティブで指定されたモジュールに暗黙的に宣言された依存関係を持つようになります。

言い換えると:

  • モジュールX requiresモジュールYの場合、
  • およびモジュールY requires transitiveモジュールZ、
  • 次に、モジュールX(暗黙的に)requiresモジュールZも。
2
manouti

accessibilityという用語はあいまいです。タイプにアクセスせずにオブジェクトにアクセスできます。オブジェクトがエクスポートされていないパッケージにあるタイプTであり、「エクスポートされた」コードにTを返すメソッドがある場合...このメソッドを呼び出すと、このTオブジェクトのハンドルが取得されます(そして、コードで既知の型に関連するメソッドを呼び出します)。

読みやすさも曖昧です:ClassLoaderが常に(エクスポートされていない)Tクラスをロードできないという意味ではありません。

0
bear