2017-11-17 16 views
2

私はIntelliJのでJava 9で遊んだ: 私は4つのモジュール(すべてのモジュールは、モジュール1に依存して)作成した:モジュール化されていないJARは、モジュール化されたJARのパッケージ化された非エクスプレッションにアクセスできるのはなぜですか?

  1. のModule1:輸出パッケージPKG1と輸出2
  2. モジュール2をモジュールにPKG2を:Module1をと
  3. 両方のパッケージにアクセスすることができるモジュール3を必要とします。Module1の
の両方のパッケージにアクセスすることができ、モジュール-info.classを持っていない:Module1をと
  • のみPKG1にアクセスすることがmodule4が必要です3210

    私は、自動モジュールでは、すべてのパッケージが公開されている必要がありますが、公開されていないものは必要としないと考えました。

    明示的にモジュール化されたJARでのみ動作する場合、カプセル化のポイントは何か分かりません。

    私には何が欠けていますか?

  • 答えて

    3

    モジュールシステムのautomatic modulesにはモジュール記述子(module-info.class)がないため、自動モジュールが依存する可能性のある他のモジュールを判断する良い方法はありません。

    モジュールグラフが解決された後、自動モジュールはで、自動か明示かにかかわらず、他のすべての名前付きモジュールを読み込みます。

    あなたのケースでは、module4は自動モジュールであり、明示的なモジュールmodule1を読み取ることができます。


    accessibility as defined in the module system(MEによって引き出さ類似度)として示されている2つのタイプSTは異なるモジュールに定義されている場合、及びTpublic、次いでSのコードはTにアクセスできる場合:

    • Sのモジュールは、Tのモジュールを読み出す(module4module1を読み出し)と

    • TのモジュールはTのパッケージをエクスポートします。 (module1輸出のみmodule2module1pckg2を必要とするすべてのモジュールにpckg1


    にアクセスできないモジュールの境界を越えて参照タイプこの方法が同様に使用不可能であることプライベートメソッドまたはフィールドが 使用不可:それを使用しようとすると、 コンパイラによってエラーが報告されるか、Java 仮想マシンによってIllegalAccessErrorがスローされるエラーが発生するか、またはIllegalAccessExceptionは、 反射実行時APIによってスローされます。

    したがって、型がパブリック宣言されていても、 は、そのパッケージは、それだけでそのモジュール内のコードにアクセスできるようになり、その後 そのモジュールの宣言でエクスポートされていない場合。あなたの例では

    +0

    これは、カプセル化をモジュール化されたJARのみに制限しますか?私はそのようなデザインの論理を理解していません。私のモジュールがパッケージを公開しないと決めた場合、それがモジュール化されたJARまたはモジュール化されていないJARによって使用されるかどうかは気にする必要がありますか?それが本当の場合は、この機能は私には壊れているようです(これはモジュールの前にも当てはまりましたが、まだ理解しています)。 – AntonKam

    +0

    @Nicolaiまあ、両方のパッケージにアクセスできるという質問がありました。モジュールが読み込んだモジュールによってエクスポートされたパッケージにアクセスできる必要があるという合意に達しました。 – nullpointer

    3

    module4pkg2にアクセスすることはできません。自動モジュール他のすべてのモジュールは(依存関係を表すことができないため)読み取られますが、rules to access typesは変更されないため、エクスポートされたパッケージのパブリックタイプにのみアクセスできます。

    あなたの引用に基づいていくつかの背景:

    私は自動モジュールがすべて公開されていないものをパッケージ化暴露ではなくを必要とするべきであると考えました。

    明示的なモジュール(すなわち、自動モジュールではない)は、他のモジュールを必要とします。実行時に必要なディレクティブはturned into readability edgesです。しかし、これらのエッジの唯一のソースではありません。自動モジュールの場合、解決された(つまり可読性グラフにされた)各モジュールにエッジが追加されます。

    「自動モジュールにはすべての公開パッケージが必要です」と言われると、いくつかの間違いがあります。翻訳で失われているかもしれませんが、私はまだ明確にしたいと思います。その文は、代わりに「自動モジュールはすべての(解決された)モジュールを読む」と言うべきである。

    この段階では、誰もアクセシビリティとパッケージについて話していません。これが次のステップです。自動モジュールは特別なものではないため、内部APIにアクセスすることはできません。

    +0

    したがって、モジュール4はパッケージpkg2にアクセスできないはずです。 コンパイルすると、intelliJで4つのモジュールを作成し、モジュール1がモジュール1に依存するようにモジュール依存関係を追加しました。そして、pkg2からクラスの新しいインスタンスを作成できます。 モジュール1からJARをビルドして、新しいプロジェクトのJARに依存関係を追加しようとしましたが、pkg2からクラスをインスタンス化することができます。 コンパイルエラーが発生する唯一のシナリオは、module-info.javaファイルをモジュールに追加してからmodule1のrequireステートメントを追加するとコンパイルが失敗することです。 – AntonKam

    +0

    モジュールは、モジュールパス上のJARからのみ作成されます。非モジュールプロジェクトをコンパイルすると、IntelliJはクラスパスに依存関係を置く可能性があります(少なくともMavenはそれを行います)。つまり、_module1_は存在しません。代わりにコンパイルされたコードとすべての依存関係は、モジュール境界が存在しない同じ名前のないモジュールになります。 – Nicolai

    +0

    下位互換性を保つために、Java 9はクラスパス上のコードの動作を変更しません。ユーザは、JARをモジュールパスに配置することによって、少なくともアプリケーションモジュールの場合はモジュールシステムを選択する必要があります。 – Nicolai

    0

    IntelliJのロジックを排除するために、私は自分のモジュール(1,4)から3つのJARを構築し、コマンドラインでjavaを使用して遊び始めました。

    -cpオプションのみを使用してコードを実行しようとすると、module4がpkg2にアクセスできるのと同じ動作をしました - >これは、IntelliJにmodule-info.javaファイルがない場合モジュールはクラスパスを使用します。

    ここでは難しい部分があります: module4の自動名がmodule4であることを確認するために--list-modulesオプションを使用しました。私はPKG1からクラス上のClassNotFoundException(エクスポートしたパッケージを)持っている

    java -p "<module1 path>;<module4 path>" -m module4/<MainClass> 
    

    : は、その後、私は次のように実行してきました。

    私が実行している場合:

    java -p "<module1 path>;<module2 path>" -m module2/<MainClass> 
    

    をその後、すべての作品。

    モジュールパスを使用したい場合、メインクラスはモジュール化されたJARでなければならないようです。

    自動JARは下位互換性のため、新しいモジュールの依存関係として使用できます。

    モジュールパスを使用してモジュールを実行する場合、Javaは実行中のJARがモジュール化されたJARであるとみなします。そうでなければ、クラスパスを使用し続ける必要があります。

    つまり、-p(modulepath)オプションを使用してモジュール化されていないJARを実行すると、パスに他のモジュールは必要ありません。

    これらの結論は、Javaで遊んできたものです。誰かがその背後にある理論の正確な部分を教えてくれますか?

    関連する問題