実際に Javaプログラムを作ったとして、1〜5ファイル程度の小さいアプリケーションであれば気にならないかもしれませんが、通常の Javaアプリケーションでは 数十ファイルから数千ファイルに及ぶ時もあります。そのような時、Javaでは用途ごとにフォルダ分けして管理を行う機能が提供されており、これをパッケージと言います。
パッケージを使うことで以下のような利点が挙げられます。
- 同じ役割を持つクラス・インタフェースを1つのパッケージにまとめることにより、そのクラス・インタフェースの持つ意味がわかりやすくなります。
- 同じ名前を持つクラス・インタフェースが複数ある場合、名前の衝突を避けることができます。
- パッケージを使用することにより、クラス・メンバ変数・メソッド・コンストラクタにアクセス制限をつけることができます。
[ packageA\ExPackage.java ]
package packageA;
public class ExPackage {
public void showName( ) {
System.out.println("PackageAに属します。");
}
}
上記では packageAというパッケージを宣言し、ExPackageクラスはそのパッケージに含まれることを表しています。このソースファイルは「packageA」フォルダ内に作成します。
パッケージ名を好き勝手に定義してしまっては、名前の衝突等で困るケースもあるため、慣習としてパッケージ名は会社のドメイン名を使用することが一般的です。例えば [ site-cooler ] という会社で開発している [ project ] という名称のシステム開発をしているとします。システムの中で役割から [ file ] というパッケージを作成したい場合、以下のようなパッケージを宣言したりします。
package com.site-cooler.project.file;
パッケージに含まれるクラスを使用したい倍、パッケージの参照方法は大きく以下の3つあります。
以下のクラス構成になっていると仮定して話を進めていきます。
com.site-cooler
|
+--com.site-cooler.project
|
+--com.site-cooler.project.root
| |
| +--com.site-cooler.project.root.RootA
| |
| +--com.site-cooler.project.root.RootB
|
+--com.site-cooler.project.file
| |
| +--com.site-cooler.project.file.FileA
| |
| +--com.site-cooler.project.file.FileB
|
+--com.site-cooler.project.db
|
+--com.site-cooler.project.db.DbA
|
+--com.site-cooler.project.db.DbB
※抽象クラスやインタフェースではなく、インスタンス化可能なクラス
参照したいパッケージのクラスをインポート
import句を使用して、参照したいクラスを明示的にインポートします。
[ com.site-cooler.project.root.RootA.java ]
import com.site-cooler.project.db.DbA;
import com.site-cooler.project.file.FileA;
public class RootA{
public static void main(String[] args){
RootB rootB = new RootB();
FileA fileA = new FileA();
DbA dbA = new DbA();
}
}
DbA と FileAの二クラスをインポートしています。RootA.java このクラスからはインポートした二つのクラスと、同一パッケージ内にある RootB がサンプルのように記述できます。 importを行っていないので「 FileA fileA = new FileA() 」のような記述は無効です。
参照したいパッケージ全体をインポート
import句を使用して、参照したいパッケージ全体を明示的にインポートします。
[ com.site-cooler.project.root.RootA.java ]
import com.site-cooler.project.file.*;
public class RootA{
public static void main(String[] args){
RootB rootB = new RootB();
FileA fileA = new FileA();
FileB fileB = new FileB();
DbA dbA = new DbA(); // DbAをインポートしていないので無効
}
}
file.* と記述することで、そのパッケージ全体をインポートしたことになります。 個々に import文を記述しなくて良くなりますが、一方で、実際にインポートしたパッケージのうちどのクラスを使用しているのか分からないというデメリットもあります。
パッケージ名を含めた限定名による参照
import句は使用しませんが、パッケージ名から指定した
限定名による参照です。。
[ com.site-cooler.project.root.RootA.java ]
public class RootA{
public static void main(String[] args){
com.site-cooler.project.file.FileB fileB = new com.site-cooler.project.file.FileB();
com.site-cooler.project.db.DbB dbB = new com.site-cooler.project.db.DbB();
}
}
import句を使用していませんが fileBと dbBの限定名を使用して別パッケージにあるクラスを参照しています。
複数のパッケージに同一のクラス名が存在する場合は注意が必要です。複数のパッケージをインポートし、単純名によりクラスを参照する際、どちらのパッケージに属するクラスかJava実行システムが判別できないため、コンパイルエラーとなります。
この場合はクラスを参照する際、パッケージ名も含めた限定名で参照するか、参照したいクラスを指定してインポートする必要がありますので気をつけましょう。