プログラミング応用a 第10回 『モジュール化その2 (パッケージ化とインポート、パッケージレベルでのアクセス制御)』  

10-6 【パッケージとディレクトリ構成】

 パッケージに属するクラスは,パッケージ構成を反映したディレクトリの中になくてはならない。
たとえば,Meibo.javaのMeiboクラスとPersonクラスは, tuisjava.com というドメインを所有して
る会社が開発した人事評価用ソフトの一部だとしよう。この2つのクラスを, com.tuisjava.jinji とい
うパッケージにまとめる場合,「com」ディレクトリの中の「tuisjava」ディレクトリの中の「jinji」
というディレクトリの中に,Meibo.classとPerson.classを置かなくてはならない(下図Fig.10参照)。

 このとき,comディレクトリを置くディレクトリ(名前は自由につけても良いが,Fig.10の例では
myclassesという名前になっている)
の場所を,コンパイラコマンドjavacや,実行コマンドjavaに,
知らせてやる必要がある。その方法には2種類あるが,それについては後ほど解説する。



実際にUnix(Linux)やWindowsのコマンドライン環境下では下記のように Meibo.java をパッケージ化できる。
ここでは,Windows のコマンドライン環境を例に解説する。

■手順0)先ほど作成した

      Meibo.java,Meibo.class ,Person.class,MeiboTest01.class

     を削除する。これらは,パッケージ化する前のものなので,もう必要がない。
     (というよりも,有ると以降の作業の邪魔になる)

■手順1)下図(Fig.10a)のように,「マイドキュメント」(Z:¥MyDocuments)ディレクトリの下に,
     myclassesディレクトリ以下,jinjiディレクトリまでを作成する(綴りを間違えないように
     気をつけること)


■手順2)Person.java(package宣言無しバージョン)Meibo.java (package宣言無しバージョン) を,
     上図のjinjiディレクトリに保存し,下図のように

      ・それぞれ1行目にpackage宣言を書き加え
      
Personクラス自体とのPersonのコンストラクタをpublicに指定
      
Meiboのコンストラクタと,put()メソッド,printAll()メソッドをpublicに指定して

     
保存し直す。







今,状況は次のようになっている。


■手順3)先ほどのMeiboTest01.java (import宣言無しバージョン) に,下図(1)のように1行目にimport宣言を付けて
     保存する。保存場所はどこでもいいが, Z:¥ooprog など,いつもjavaのプログラムを作成しているディレク
     トリでよだろう。


      次に,このMeiboTest01.javaをコンパイルするわけだが,このプログラムはimport宣言にあるように,
      com.tuisjava.jinji パッケージのMeiboクラスを利用する。

      前述したように,パッケージ化したクラスを利用するには,コンパイル時とプログラム実行時に,
       ・パッケージの起点となるディレクトリ(Fig.10の例ではmyclassesディレクトリ)の場所
     を,javacコマンドや,javaコマンドに教えておく必要がある。(ちなみに,コンパイルやプログラムの実行時
     に必要になるクラスの場所を示すファイルパス(file path name)のことを,クラスパス(class path)と呼ぶ。ここ
     で指定するパッケージの起点となるディレクトリの場所もクラスパスの一種である)

      パッケージの起点となるディレクトリの場所をjavac/javaコマンドに教える方法には,次の2つがある。
       i) コンパイル時やプログラム実行時に,そのつどパッケージの起点となるディレクトリの場所を指定する
       ii) 環境変数CLASSPATHに,パッケージの起点となるディレクトリの場所を追加する
     ここでは,i)の方法を紹介する。(ii)の方法についてはこちらを参照)

     コンパイルは,次のように行う。

       (1) コマンドプロンプトを表示して,MeiboTest01.java を保存したディレクトリにcdコマンドで移動。
         例:もし,MeiboTest01.java を Z:¥ooprog に保存しているなら,
            > cd Z:¥ooprog
           とする。

       (2) 次のように,パッケージの起点となるディレクトリの場所を指定してMeiboTest01.java をコンパイルする。
         > javac -cp "Z:\MyDocuments\myclasses" MeiboTest01.java
               ※-cpは,javacコマンドのクラスパスを指定するためのオプションである。javacコマンドのオプションについては
                 > javac -help
                とすれば概要が表示される。

     コンパイルがうまくいかない場合は,

       ・ファイル配置が,手順2のFig.10のようになっているか(ディレクトリ名の間違いなどにも注意)
       ・Meibo.javaに,正しくpackage宣言が書かれているか
       ・MeiboTest01.javaに,正しくimport宣言が書かれているか

     を確認する。

     コンパイルがうまくいくと,Meibo.class と Person.class が jinji ディレクトリの中に出来ているはずであるので,
     確認する(下図)。


     ここで起こったことを順序立てて書くと次のようになる。

      1)javacコマンドが MeiboTest01.java をコンパイルするとき,必要になるMeiboクラスが見つか
        らないので,-cpオプションで指定されたファイルパスによりパッケージ階層の起点であるディ
        レクトリ(この場合,Z:\MyDocuments\myclasses)を割り出す。

      2)次いで,パッケージ階層の起点ディレクトリ(myclasses)とimport宣言の内容から

          Z:\MyDocuments\myclasses\com\tuisjava\jinji

        ディレクトリにクラスファイル Meibo.class があるのではないかと推測する。

      3)しかし,そのjinjiディレクトリ内には,コンパイル済みの Meibo.class はまだ無い。そこで
        javaコンパイラは,Meiboクラスを定義しているはずのソースファイル Meibo.java を探す。そ
        うして,jinjiディレクトリ内に Meibo.java を見つけたjavaコンパイラは,Meibo.java を
        コンパイルしてjinjiディレクトリの中に,Meibo.class と Person.class を生成したのである
        (上図の矢印)。Personクラスについても同様である。

■手順6)手順の5でコンパイルした MeiboTest01.class を実行してみる。コマンドプロンプトの現在位置
     (カレントディレクトリ)に MeiboTest01.class があることを確認する。実行コマンドは以下のよう
     になる。クラスパスに,MeiboTest01.class の在処であるカレントディレクトリ(.)を追加している
     ことに注意。なお,カレントパスの区切り文字はWindowsではセミコロン(;),Unixではコロン(:)が
     使われる。
      > java -cp "Z:\MyDocuments\myclasses;." MeiboTest01
             ※-cpは,javaコマンドのクラスパスを指定するためのオプションである。javaコマンドのオプションについては
               > java -help
              とすれば概要が表示される。


※Eclipseで,パッケージを扱う方法については,左欄の「4. Eclipseでパッケージを作成する方法」のリンク先を参照せよ。