モジュール管理とパッケージの概念
本格的なアプリケーション開発を行うようになると、
多くのクラスのモジュールを管理する必要が生じます。
ここでは、その中心となる「パッケージ」の利用法を紹介します。
そのルールは非常にシンプルで、しかもマシンやシステムにはほとんど依存しません。
Java言語では、クラスはとても簡単なルールによって管理されています。
-
Javaのソースファイルがコンパイルされると、その中で定義された各クラスは、
それぞれ独立した「バイトコード」になります。
このバイトコードが Javaにおけるモジュールの基本単位となります。
バイトコードの名前が「クラス名 + .class」というルールで付けられます。
-
1つのソースファイル内に複数のクラス定義が存在されている場合には、
それらはそれぞれのクラス定義の内部で互いを参照し合うことが可能です。
共通のソースファイルに含まれるクラスの集まりを「コンパイル単位」と呼びます。
-
各コンパイル単位は package文によって、
それが所属する「パッケージ」名を宣言することができます。
同じパッケージ名を宣言したコンパイル単位は、
共通したパッケージに含まれることになります。
パッケージの内部と外部では、アクセス・モードの解釈が異なります。
-
パッケージ名は .(ピリオド)で区切られた階層構造を構成することが可能です。
「クラスライブラリ」(もしくは大規模なアプリケーション)は、
それ自身が1つのパッケージですが、
多くの場合いくつかの「サブ・パッケージ」に分かれているのが普通です。
クラスライブラリとアプリケーションは管理のルールの面では同じで、
利用される時の形態が異なるだけです。
クラスライブラリは多くの public なクラスを提供して、
他のアプリケーションに活用されます。
一方アプリケーションの場合は、
中心となるクラスが Javaインタープリタから起動され、
他のクラスのモジュールを呼び出すことになります。
Java言語のクラス管理の階層
| バイトコード |
コンパイル単位 |
パッケージ |
クラスライブラリ (アプリケーション) |
| 単独のクラス |
同一のソースファイル |
パッケージ名が共通 |
階層構造を持つパッケージ |
もちろん、1つのクラスのみを含むコンパイル単位、
単独のコンパイル単位のみのパッケージ、
サブ・パッケージを含まないクラスライブラリが存在してもかまいません。
ソースファイル内でパッケージ名を指定しない場合は、
暗黙のうちに「名前なしのパッケージ」という共通のパッケージに
含まれると解釈されます。
アプリケーションの規模が小さい場合は、これで特に問題ありません。
ただし大規模な開発を行う場合は、クラス名の衝突を防ぐためにもパッケージ名
の指定が必要になってきます。
各サブ・パッケージの階層構造は、現実のファイルシステムのディレクトリ構造に
対応させるルールになっています。
クラスライブラリにアクセスするには、
その「ルート・ディレクトリ」に該当する場所を「クラスパス」として指定します。
上のルールは非常に明快ですが、現実にファイルの数が増えてくると管理が面倒です。
クラスライブラリの「アーカイブ」に当たるものが利用できると便利でしょう。
現在の JDKでは、zip形式に圧縮されたファイルを、現実のファイルシステムと
同様に取り扱うことができます。
その場合、圧縮されたファイルが存在するディレクトリをクラスパスに指定します。
また、それらの機能を利用するために java.util.zip パッケージが提供されています。
パッケージを明示するには、
ソースファイルの先頭で package文によってパッケージ名を宣言します。
package文は必ずソースの先頭に置かなくてはなりません。
たとえば、EchoCommandクラスを commands という名前の
パッケージに含めたいとしたならば、以下のようにします。
package commands;
/** 引数をメッセージを標準出力に表示するクラス */
public class EchoCommand {
/** 処理の開始のメソッド */
public static void main( String argv[] ) {
for( int i=0; i
パッケージを宣言することによって以下のような利点が生じます。
- 「互いに関連があるクラスを1つのグループにまとめて管理できる」:
これは既に説明してきたことからおわかりでしょう。
開発中の管理にも便利ですし、完成した後、1つの製品として
提供するためにも必要なことです。
- 「他のパッケージとの間でクラス名の衝突を防ぐことができる」:
アプリケーションが大規模になってくると、部品として利用されるクラスも
増えてきます。
そうなるとクラスの命名にも注意が必要です。
たとえば、Cell とか ImageButton などのような名前のクラスは
多くの場所で使われそうです。
protected もしくは宣言なしのアクセスモードを用いて、
パッケージ(あるいはサブ・パッケージ)の内部のみで
アクセスできるようにしておけば、より安全です。
- 「データへのアクセスに制限をつけることでバグを防止できる」:
内部の処理で使われるデータに対しては、やはり protected もしくは宣言なしの
アクセスモードを用いて、
パッケージの外部のオブジェクトからアクセスを許さないようにできます。
それによって、プログラムの全く離れた場所が原因でバグを発生させる
ことは未然に防ぐことができます。
発生したバグの原因を捜す範囲もせばまり、
アプリケーションの保守の労力も軽減されることになります。