新しいテーマでの演習問題に取り組みましょう。
問題
次のモジュール宣言について、正しいものを選んでください。
// ModuleAのmodule-info.java
module ModuleA {
exports com.moduleA;
}
// ModuleBのmodule-info.java
module ModuleB {
requires ModuleA;
}
// ModuleCのmodule-info.java
module ModuleC {
exports com.moduleC;
requires ModuleB;
}
// com.moduleCのMain.java
package com.moduleC;
import com.moduleA.SomeClass;
public class Main {
public static void main(String[] args) {
SomeClass obj = new SomeClass();
System.out.println(obj.getMessage());
}
}
選択肢
- A. ModuleCはModuleAのクラスを直接使用できる
- B. ModuleCはModuleAをrequiresする必要がある
- C. ModuleBがModuleAをexportsしないと、ModuleCはModuleAを使用できない
- D. ModuleCはModuleAのクラスを使用できない
答えと解説
回答を見る
答え
D. ModuleCはModuleAのクラスを使用できない
解説
基本説明:
Java SE 9以降では、モジュールシステムが導入されています。これにより、プログラムをモジュールという単位で管理することが可能になりました。
モジュール宣言は通常、`module-info.java`ファイルで行われ、そこでは、公開するパッケージ (`exports`) や、依存する他のモジュール (`requires`) を指定します。モジュールBがModuleAを`requires`している場合、ModuleBのコンテンツはModuleAの公開内容にアクセスできます。しかし、ModuleCはModuleAに対して直接的な依存関係を持たないため、ModuleAのクラスを使用することができません。
誤答理由:
A. ModuleCがModuleAを直接利用することはできません。ModuleBがModuleAを利用しているだけで、ModuleBが再エクスポートしない限り、間接的な使用はできません。
B. ModuleCがModuleAを直接`requires`に追加すれば、利用可能ですが、その宣言が見当たりません。
C. ModuleBの再エクスポートがない限り、ModuleCがModuleAのパッケージを直接使用する方法はありません。
つまずきポイント:
モジュールシステムは複雑で、各モジュールの依存関係やエクスポートの設定が正確でないと、予想外の制限やエラーが発生します。
モジュールの意図しない利用を防ぐために、`exports`の設定によってアクセス制御を行う点が理解しづらいことがあります。
発展知識:
Javaモジュールシステムでは、モジュール再利用のための再エクスポートという概念があります。`requires`+`exports`の組み合わせにより、あるモジュールが別のモジュールを参照し、同時に利用可能な形でエクスポートすることが可能です。
この仕組みにより、抽象化層を持つ規模の大きいJavaアプリケーションを効率よく構築することができます。