Java のパッケージ
Java のコードは「パッケージ」で整理する
「Java の分割コンパイルと CLASSPATH」では、 TestApp の実行時に、 Person クラスを見つけるために、クラスパスを設定するということについて説明しました。
その際、 Person クラスは TestApp が保存されているディレクトリのサブディレクトリである dir1 ディレクトリに保存しました。
しかし Java ではクラスを整理するためには、通常 パッケージ (package) を利用します。
Java のパッケージはディレクトリで整理する
それでは具体的に、パッケージはどのようなものでしょうか?
パッケージはクラス名を階層構造に整理するものです。例えば、 Dog というクラスを animals というパッケージに配置すれば、 animals.Dog クラスとして認識できるようになります。
Java では基本的にファイル名とクラス名が同じです。
それと同様に、パッケージ名はディレクトリ構造と関連付けます。
例えば animals.Dog クラスは、 animals ディレクトリの中の Dog.java ファイルとして作ります。
もし animals.pets.Dog クラスにするなら、 animals ディレクトリの中に pets ディレクトリを作成して、その中に Dog.java を作成するという風にします。
Java のパッケージ名の命名規則
パッケージ名は通常、インターネットドメインを逆にした形式のパッケージ名とします。
例えば当サイトは java.keicode.com というドメイン名です。 この場合、パッケージ名として com.keicode.java.samples のようにします。
文字にハイフン等の記号、数字始まり、Java のキーワード (int 等) を含む場合は _ (アンダースコア) をつけます。例えば 1foo.com というドメイン名に対しては com._1foo とします。
ハイフンはそのままアンダースコアに置き換えます。(abc-xyz.com は com.abc_xyz とします)
また、パッケージ名は通常、全て小文字とします。
こうした命名規則は、名前の衝突による混乱を未然に防ぐために奨励されている、ということであって、 このような名前をつけないとプログラムが実行できない、とか、コンパイルできないというようなものではありません。当サイトの記事では、基本的にはシンプルなパッケージ名を用います。
Java の package 文
それでは前の記事「Java の分割コンパイルと CLASSPATH」で書いたプログラムを、パッケージを使って少し整理してみましょう。
まず、サブディレクトリを dir1 としていましたが、これを mypackage というディレクトリ名に変更しましょう。
そしてサブディレクトリ mypackage 内に Person.java を保存します。
Person.java では package文を用いて、パッケージ mypackage 内にあることを明示します。
package mypackage;
public class Person {
private int age;
private String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public void printName() {
System.out.println(this.name);
}
public void printAge() {
System.out.println(this.age);
}
}
この 1 行目が package 文です。
Java の import 文
パッケージ内のクラスを利用する側では、 import 文を使って利用するクラス名を指定します。
ソースコードで import mypackage.Person と記述すれば、Person として mypackage.Person クラスが使えます。
TestApp.java では import 文で mypackage.Person クラスを取り込みます。
import mypackage.Person;
public class TestApp {
public static void main(String[] args) {
Person p = new Person(20, "John Doe");
p.printName();
p.printAge();
}
}
前回の記事ではクラスパスを指定することで、どうにか Person クラスを発見しました。 今回は package 文と import 文を使って明示的にパッケージを指定することで、曖昧なところのない形でクラスを見つけることができるようになります。
パッケージ内に複数のクラスがあり、全てを取り込む場合は import mypackage.*; という風にワイルドカードを使うこともできます。
その他、パッケージ名を含む完全修飾名として、 mypackage.Person として特定のクラスであることを明示することもできます。同名のクラスが異なるパッケージに存在する時には、完全修飾名を使うと良いでしょう。