【Java学習|初心者向け】Java 9からの必須知識!モジュールシステムにおける「exports」の役割を徹底解説

1. 導入: なぜ「パッケージの公開」が必要なのか

Java 9で導入された「Javaモジュールシステム(Project Jigsaw)」により、Javaのプロジェクト構成は大きく変わりました。これまでのJavaでは、クラスパス上のすべてのクラスは「どこからでもアクセス可能」でしたが、モジュールシステムではデフォルトで隠蔽(カプセル化)されるようになりました。
「exports」は、自分のモジュール内のパッケージを「外部から使えるようにする」ための唯一の入り口です。なぜこれが必要かというと、内部でしか使わない複雑な処理や、外部に公開すべきでない設計を強制的に隠すことで、アプリケーションの堅牢性とセキュリティを向上させるためです。

2. 基礎知識: module-info.java とは

Javaモジュールシステムの中核を担うのが、プロジェクトのルートディレクトリに配置する「module-info.java」というファイルです。
このファイルには、そのモジュールの名前や、依存関係、そして公開するパッケージ(exports)を記述します。

モジュール: 関連するパッケージをまとめた単位。
exports: 指定したパッケージ内の public クラスを、他のモジュールから参照可能にするキーワード。
opens: リフレクション(実行時のクラス解析)を許可するためのキーワード。

3. 実装/解決策: exports の記述方法

モジュールを定義するには、module-info.java に以下のように記述します。

module com.example.service {
// com.example.service.api パッケージを外部に公開する
exports com.example.service.api;
}

これだけで、他のモジュールからは com.example.service.api 内の public クラスにしかアクセスできなくなります。これにより、開発者は「外部に公開する API」と「内部だけで動く実装」を明確に分離できます。

4. サンプルプログラム

以下の構成で、モジュールを定義する例を示します。

// ファイル名: module-info.java
module my.app.core {
// このパッケージを他のモジュールから利用できるように公開します
exports com.myapp.publicapi;
}

// ファイル名: src/com/myapp/publicapi/GreetingService.java
package com.myapp.publicapi;

public class GreetingService {
public void sayHello() {
System.out.println(“こんにちは!モジュールシステムへようこそ。”);
}
}

// ファイル名: src/com/myapp/internal/HiddenLogic.java
package com.myapp.internal;

// このパッケージはexportsしていないため、外部モジュールからは見えません
public class HiddenLogic {
public void execute() {
System.out.println(“これは外部から隠された内部ロジックです。”);
}
}

5. 応用・注意点: 現場でのハマりポイント

現場でよくある失敗は、「パッケージ名が変わったのに module-info.java を更新し忘れる」ことです。
また、Spring FrameworkやHibernateのようなライブラリを使う場合、単に public にするだけでなく、「リフレクション」によるアクセスが必要になることがあります。その場合は、exports ではなく opens を使って公開設定を行う必要があります。

注意点:
・exports はパッケージ単位であり、クラス単位では指定できません。設計段階で公開したいクラスを特定のパッケージにまとめておくことが重要です。
・モジュール化されていないライブラリ(名前のないモジュール)と混在させる場合は、依存関係の解決に少し工夫が必要になるため、まずは小規模なプロジェクトからモジュール化を試すことをおすすめします。

モジュールのカプセル化を理解すると、大規模開発での依存関係が整理され、非常にメンテナンスしやすいコードになります。ぜひ今日から module-info.java を活用してみてください!

コメント

タイトルとURLをコピーしました