LoginSignup
1
1

More than 1 year has passed since last update.

Javaのモジュールについてまとめてみた

Posted at

Javaのモジュールシステムについてまとめてみました。

Java9から実装された機能なのでかなり古いですが、やってみます。

Javaのモジュールシステムとは

・パッケージの依存関係を簡潔に整理させる
・パッケージのアクセスを制御することができる

これらの利点を得るためにJava9で実装されたものです。
これにより、不用意に他のプログラムからのアクセスを拒否することができます。そうして
「え、このコード動かして実装してみたら他のところでバグが起きちまった!クソスパゲティーコードが!!!!」
といったことがなくなります。筆者もmoduleではないですが、コードを書いていたら別のところがバグってしまい、「そこにアクセスするんじゃねぇよ」と思った経験があります。
そういたことを防ぐためにあるわけですね。

Java9よりも細かくアクセスできるスコープを設定できます。具体的には

・今作業しているモジュールの中でだけpublic
・指定したモジュールに対してだけpublic
・すべてのモジュールに対してpublic

ということができます。

そして、Java9ではすべての標準ライブラリもmodule化されています。

moduleの定義の仕方

module モジュール名{
        処理
}

moduleの中に書く内容

この中で、System.out.println()とか書いてはいけません。
これをやりたいのであればmoduleではなくインターフェースを使いましょう。
moduleの中に書く内容は、あくまでもパッケージやライブラリを参照させるのか、参照させないのか、はたまた参照するのかなので、それについては今から説明します。

中に各処理としては主に三種類あります

・requires宣言
・requires transitive宣言
・exports宣言

です。
これからそれらについて詳しく解説していきます。

requires宣言

デフォルトではすべてのmoduleは他のmoduleに対してアクセスする事はできません。
しかし、requires宣言することで、別のmoduleを使用したい時に使用することができるようになります。
書き方としては以下です。

SampleModule.java
module SampleModule {
    requires java.net.http;
}

これでava.net.http;をSampleModulesに依存させることができます。ちなみにこれはHTTPリクエストに対するmoduleです。
ただ、これではmoduleAに対してmoduleBの持っているmodleCを依存させたい場合、moduleAはmoduleCに対して直接requiresを宣言させ無いといけません。
これをしてしまうと、moduleAとmoduleCの関係をmoduleの名前からわかりやすく理解させることが難しくなってしまうし、moduleCだけでは足りなくてmoduleBにもrequires宣言をしないと行けなくて、結果的にコードの全体図が把握できないなどの弊害も出てきてしまいます。

その解決方法を次に解説します。

requires transitive宣言

こちらを使うことで、moduleAに対してmoduleBを介して、moduleCの内容を参照させる事ができるようになります。

イメージとしては踏み台サーバーのようなものです。

書き方としては以下です

SampleModules.java
module SampleModule {
    requires transitive java.net.http;
}

になります。
先程のrequires宣言にtransitiveをつけるだけです。
こうすることで、先程の問題を解消することができます。
ちなみにこうしてmoduleを介して別のmoduleの内容を参照させることを、

推移的な依存関係を宣言する

といいます。

そして、ついに最後になった宣言のやり方を解説していきます。

exports宣言

デフォルトでは、moduleはmoduleの外からはアクセスできない様になってします。
それを、どこまで公開するのかを調整するのが、exports宣言です。

まずはじめに、全体に対して公開するやり方について説明していきたいと思います。

やり方としては、

SampleModule.java
module SampleModule {
    exports com.example.hoge.huge;
}

このcom.example.hoge.hugeの部分を参照させたいmoduleの名前に変えるだけです。
こうすることで、moduleの外からのアクセスをすべて許可します。

しかし、コーディングのルールによってはすべてのアクセスを許可する場合でもどこからの参照を許可するのかを明示的にしないといけない場合もあると思います。
なので、今からそのアクセスを制限するやり方について説明していきたいと思います。

やり方は以下です。

SampleModules.java
module SampleModule {
    exports com.example.hoge.huge to aaa, bbb;
}

このように、toを使ってつなげ、aaaとbbbの部分を指定したいmoduleの名前に変えるだけです。
こうすることで、指定した場所にのみmoduleを公開することができました。

今回は以上になります。
ありがとうございました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1