Java Gold 17のモジュール対策|requires・exports・opens

モジュールの問題では「どのモジュールを読むか」と「どのパッケージを公開するか」を分けて考えます。宣言の向きと、コンパイル時・実行時の役割を整理しましょう。

requires・exports・opensの違い

宣言指定する対象役割
requiresモジュール名自分が依存するモジュールを指定します。
exportsパッケージ名外部から通常のコードでアクセスできるパッケージを指定します。publicなどのアクセス修飾子も引き続き適用されます。
opensパッケージ名実行時のリフレクションによるアクセスを許可します。通常のimportのための公開とは異なります。

exports p to consumer;のpはパッケージ、consumerはモジュールです。限定公開の対象に含まれないモジュールには、この宣言による通常のアクセスは許可されません。

依存関係は矢印で整理する

Aがrequires B;を宣言すると、AからBを読む関係になります。Bが自動的にAを読めるようになるわけではありません。また、AがBを読めても、Bが対象パッケージをAへ公開しているかは別に確認します。

Bがrequires transitive C;を宣言している場合は、Bを読む側にもCへの可読性が伝わります。一方、requires staticはコンパイル時には必要で、実行時には任意の依存を表します。transitiveとstaticを同じ意味で覚えないようにしましょう。

コマンドでは、--module-pathがコンパイル済みモジュールの探索先です。ソースを置く場所と混同しないよう、問題文で「どのファイルがすでに存在するか」を先に整理します。宣言の詳細はJava SE 17言語仕様のモジュール宣言、オプションはjavacの公式仕様で確認できます。

例題2問:限定公開とモジュールパス

モジュール名とパッケージ名を区別し、利用する側から依存関係を追ってください。

例題1:限定exportsと可読性

alpha.apiを読むbeta.uiとgamma.jobがあります。次の宣言について正しい説明を2つ選んでください。

module alpha.api {
    exports alpha.publicapi;
    exports alpha.privateapi to beta.ui;
}
// beta.uiとgamma.jobはいずれも requires alpha.api; を宣言済み

2つ選択してください

  • A. beta.uiのrequiresだけでalpha.apiからbeta.uiへの可読性も生まれる
  • B. gamma.jobはalpha.privateapiのpublic型も使える
  • C. gamma.jobはalpha.publicapiのpublic型を使える
  • D. beta.uiはalpha.privateapiのpublic型を通常のコードから使える
例題1の正解・解説を見る

正解:C・D

可読性があることと、その利用側へ対象パッケージが公開されていることの両方が必要です。

可読性があることと、その利用側へ対象パッケージが公開されていることの両方が必要です。

  • A:requiresの依存方向は一方向です。
  • B:gamma.jobは限定exportsの対象外です。
  • C:このパッケージは限定せず公開されています。
  • D:限定exportsの対象にbeta.uiが指定されています。

確認するポイント:exportsの後はパッケージ名、toの後はモジュール名です。

仕様を確認するための公式資料:

問題ID:jg17-773d41c6d95a8a · この問題の訂正を連絡する

例題2:依存モジュールの探索先

lab.cliはlab.coreに依存します。コンパイル済みlab.coreがmods/lab.coreにある場合、次のコマンドへ追加するオプションを選んでください。

javac -d out/lab.cli src/lab.cli/module-info.java src/lab.cli/app/Run.java

1つ選択してください

  • A. --class-path src
  • B. --source-path mods
  • C. --module-path mods
  • D. --module mods
例題2の正解・解説を見る

正解:C

正解は「--module-path mods」です。

--module-pathは依存するコンパイル済みモジュールの探索先です。modsの下のlab.coreを見つけてrequiresを解決できます。

  • A:依存する名前付きモジュールをソース用クラスパスでは解決できません。
  • B:コンパイル済みの依存モジュールを探す指定ではありません。
  • C:--module-pathは依存するコンパイル済みモジュールの探索先です。modsの下のlab.coreを見つけてrequiresを解決できます。
  • D:--moduleはコンパイル対象モジュール名であり探索先ではありません。

確認するポイント:ソースの探索先と、コンパイル済み依存モジュールの探索先を区別します。

仕様を確認するための公式資料:

問題ID:jg17-8f249afceea65a · この問題の訂正を連絡する

モジュールシステムの43問で復習する

問題演習の「出題分野」で「モジュールシステム」を選ぶと、43問の演習ができます。これは本サイトの分類・収録数です。

誤答したら、可読性・公開範囲・探索先のどれを取り違えたかをメモします。さらにサービスのuses・provides、jdeps・jlink・jmodの役割も公式の試験範囲と照合して学んでください。

次に取り組む学習

問題は本試験の過去問ではなく、Java SE 17を学ぶためのオリジナル練習教材です。編集・訂正の方針をご確認ください。