Javaパッケージ完全ガイド: 名前空間管理・アクセス制御・ディレクトリ構造・CLASSPATH設定
Javaでは、命名競合を防ぎ、アクセスを制御し、クラス、インターフェース、列挙型、アノテーションの検索/位置特定と使用を容易にするためにパッケージを使用します。
パッケージとは、関連する型(クラス、インターフェース、列挙型、アノテーション)のグループ化であり、アクセス保護と名前空間管理を提供します。
Javaの既存パッケージの一部:
java.lang- 基本クラスをバンドルjava.io- 入出力機能のクラスをバンドル
プログラマは独自のパッケージを定義して、クラス/インターフェースなどのグループをバンドルできます。自分で実装した関連クラスをグループ化することは良い習慣です。これにより、プログラマはそれらのクラス、インターフェース、列挙型、アノテーションが関連していることを容易に判断できます。
パッケージは新しい名前空間を作成するため、他のパッケージの名前との競合がありません。パッケージを使用すると、アクセス制御が容易になり、関連クラスの位置特定も容易になります。
パッケージの作成
パッケージを作成する際、パッケージ名を選び、その名前でpackageステートメントを、クラス、インターフェース、列挙型、アノテーション型を含むすべてのソースファイルの先頭に記述します。
packageステートメントはソースファイルの最初の行でなければなりません。各ソースファイルには1つのpackageステートメントのみ記述でき、そのファイル内のすべての型に適用されます。
packageステートメントを使用しない場合、クラス、インターフェース、列挙型、アノテーション型は現在のデフォルトパッケージに配置されます。
パッケージステートメントを含むJavaプログラムをコンパイルするには、以下のように-dオプションを使用します。
javac -d Destination_folder file_name.java
すると、指定された宛先にパッケージ名のフォルダが作成され、コンパイルされたクラスファイルがそのフォルダに配置されます。
例: animalsパッケージの作成
パッケージ名には小文字を使用するのが良い習慣です。これによりクラス名やインターフェース名との競合を避けられます。
以下のパッケージ例にはanimalsというインターフェースが含まれます。
/* File name : Animal.java */
package animals;
interface Animal {
public void eat();
public void travel();
}
次に、同じパッケージanimalsで上記インターフェースを実装します。
package animals;
/* File name : MammalInt.java */
public class MammalInt implements Animal {
public void eat() {
System.out.println("Mammal eats");
}
public void travel() {
System.out.println("Mammal travels");
}
public int noOfLegs() {
return 0;
}
public static void main(String args[]) {
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
以下のようにJavaファイルをコンパイルします。
$ javac -d . Animal.java
$ javac -d . MammalInt.java
カレントディレクトリにanimalsという名前のパッケージ/フォルダが作成され、クラスファイルが配置されます。
importキーワード
クラスが同じパッケージ内の別のクラスを使用する場合、パッケージ名を使用する必要はありません。同じパッケージ内のクラスは特別な構文なしで互いを見つけられます。
例
ここではBossクラスがpayrollパッケージに追加され、既にEmployeeが含まれています。Bossは以下のクラスで示すように、payrollプレフィックスなしでEmployeeクラスを参照できます。
package payroll;
public class Boss {
public void payEmployee(Employee e) {
e.mailCheck();
}
}
もしEmployeeクラスがpayrollパッケージにない場合はどうなるでしょうか?Bossクラスは、異なるパッケージのクラスを参照するために以下のいずれかの手法を使用する必要があります。
- クラスの完全修飾名を使用する。例:
payroll.Employee
importキーワードとワイルドカード(*)を使用してパッケージをインポートする。例:
import payroll.*;
importキーワードを使用してクラス自体をインポートする。例:
import payroll.Employee;
注意 - クラスファイルには任意の数のimportステートメントを含められます。importステートメントはpackageステートメントの後、クラス宣言の前に記述しなければなりません。
パッケージのディレクトリ構造
クラスがパッケージに配置されると、2つの主要な結果が生じます。
- パッケージ名がクラス名の一部になる(前節で説明済み)。
- パッケージ名が、対応するバイトコードが存在するディレクトリ構造と一致しなければならない。
Javaでファイルを管理するシンプルな方法:
クラス、インターフェース、列挙型、アノテーション型のソースコードを、型の単純名をファイル名とし、拡張子を.javaとしたテキストファイルに配置します。
例:
// File Name : Car.java
package vehicle;
public class Car {
// クラス実装
}
ソースファイルを、クラスが属するパッケージ名を反映したディレクトリに配置します。
....\vehicle\Car.java
修飾クラス名とパス名は以下のようになります。
- クラス名 →
vehicle.Car - パス名 →
vehicle\Car.java(Windowsの場合)
一般的に、会社は反転させたインターネットドメイン名をパッケージ名に使用します。
例 - 会社のインターネットドメイン名がapple.comの場合、すべてのパッケージ名はcom.appleで始まります。パッケージ名の各コンポーネントはサブディレクトリに対応します。
例 - 会社がcom.apple.computersパッケージを持ち、その中にDell.javaソースファイルがある場合、以下のような一連のサブディレクトリに含まれます。
....\com\apple\computers\Dell.java
コンパイル時に、コンパイラは定義されている各クラス、インターフェース、列挙型に対して異なる出力ファイルを作成します。出力ファイルのベース名は型の名前で、拡張子は.classです。
例:
// File Name: Dell.java
package com.apple.computers;
public class Dell { }
class Ups { }
以下のように-dオプションを使用してコンパイルします。
$ javac -d . Dell.java
ファイルは以下のようにコンパイルされます。
.\com\apple\computers\Dell.class
.\com\apple\computers\Ups.class
\com\apple\computers\で定義されているすべてのクラスやインターフェースを以下のようにインポートできます。
import com.apple.computers.*;
.javaソースファイルと同様に、コンパイルされた.classファイルもパッケージ名を反映した一連のディレクトリに配置されるべきです。ただし、.classファイルへのパスは.javaソースファイルへのパスと同じである必要はありません。ソースとクラスのディレクトリを別々に配置できます。
<path-one>\sources\com\apple\computers\Dell.java
<path-two>\classes\com\apple\computers\Dell.class
このようにすることで、ソースを公開せずにクラスディレクトリへのアクセスを他のプログラマに提供できます。また、コンパイラとJava仮想マシン(JVM)がプログラムで使用するすべての型を見つけられるように、ソースとクラスファイルをこの方法で管理する必要があります。
クラスディレクトリへのフルパス、<path-two>\classesはクラスパスと呼ばれ、CLASSPATHシステム変数で設定されます。コンパイラとJVMの両方が、クラスパスにパッケージ名を追加して.classファイルへのパスを構築します。
<path-two>\classesがクラスパスで、パッケージ名がcom.apple.computersの場合、コンパイラとJVMは<path-two>\classes\com\apple\computersで.classファイルを探します。
クラスパスには複数のパスを含められます。複数のパスはセミコロン(Windows)またはコロン(Unix)で区切ります。デフォルトでは、コンパイラとJVMはカレントディレクトリとJavaプラットフォームクラスを含むJARファイルを検索するため、これらのディレクトリは自動的にクラスパスに含まれます。
CLASSPATHシステム変数の設定
現在のCLASSPATH変数を表示するには、WindowsとUNIX(Bourne shell)で以下のコマンドを使用します。
- Windows →
C:\> set CLASSPATH - UNIX →
% echo $CLASSPATH
CLASSPATH変数の現在の内容を削除するには:
- Windows →
C:\> set CLASSPATH = - UNIX →
% unset CLASSPATH; export CLASSPATH
CLASSPATH変数を設定するには:
- Windows →
set CLASSPATH = C:\users\jack\java\classes - UNIX →
% CLASSPATH = /home/jack/java/classes; export CLASSPATH
Java
- Pythonパッケージ:構造、インポート、ベストプラクティス
- Javaのfinalキーワード完全解説:変数、メソッド、クラスでの活用法
- Java instanceof演算子完全ガイド:基本から継承・インターフェースまで
- Java継承のマスター:概念、種類、実践例
- Java Staticネストクラスの理解:用法、違い、実例
- Java無名インナークラス完全ガイド:定義、構文、実践例
- Javaシングルトンパターン完全解説:安全な実装と活用法
- Javaリフレクション完全ガイド:実行時のクラス・メソッド・フィールド検査
- Java ObjectOutputStream完全ガイド:シリアル化、メソッド、実践例
- Javaジェネリクス完全ガイド:再利用可能で型安全なコードの構築
- Javaファイル操作のマスター:java.ioによる作成・読み取り・書き込み・削除