パッケージとはクラス(.class)ファイルの集まりを示すものであり、パッケージを使用することで複数のクラス(.class)ファイルを分類し、管理することができます。またこれにより、クラス(.class)ファイルは「パッケージ名+ファイル名」のように名前空間(Namespace)が与えられて、名前の一意性も高まります。
ちなみにJavaはその仕様上、クラス(.class)ファイルを必ずどこかのパッケージに収める必要があります。その為、パッケージを明示していない(いままでのような)クラス(.class)ファイルは「デフォルトパッケージ」という形で取り扱っています。
パッケージの指定およびパッケージ内のファイルを呼び出す方法は次の通りです。
package パッケージ名;
パッケージ名はこのファイルを含めるディレクトリ名となります。よってディレクトリを階層的にすることでパッケージも階層的に使用することが出来ます。階層的なパッケージの指定方法は次のように各パッケージを「.」(ピリオド)で区切って明記します。
package パッケージ名1.パッケージ名2. ・・・;
パッケージ内のクラスやインタフェースを使用するときは、次のように呼び出します。(絶対ファイル名指定)
パッケージ名.クラス名 パッケージ名.インタフェース名
1.パッケージのサンプルソース(Package1301.java)
package package1;
public class Package1301 {
public String getName() {
return "「package1」パッケージ内の「Package1301」クラスです。";
}
}
2.サンプルクラスの呼び出し(Sample1301.java)
public class Sample1301 { public static void main(String[] args) { // パッケージ「package1」のクラス「Package1301」を使用するときは次のようになります。 package1.Package1301 pk = new package1.Package1301(); System.out.println("使用したクラスは"); System.out.println(pk.getName()); } }
・コンパイル及び実行結果
まずパッケージのフォルダーを作成し、次にパッケージに含めるファイルを置きます。
C:\>cd c:\dev\java [Enter] ← ファイルを保存したフォルダーへ移動。 C:\dev\java>dir [Enter] ← フォルダー内を確認。 ドライブ C のボリューム ラベルは Local Disk です ボリューム シリアル番号は 001A-E4E3 です C:\dev\java のディレクトリ 2008/03/16 09:38 <DIR> . 2008/03/16 09:38 <DIR> .. 2008/03/16 09:29 161 Package1301.java 2008/03/16 09:30 332 Sample1301.java 2 個のファイル 493 バイト 2 個のディレクトリ 52,261,765,120 バイトの空き領域 C:\dev\java>mkdir package1 [Enter] ← パッケージ「package1」の作成。 C:\dev\java>move Package1301.java package1 [Enter] ← パッケージ(package1)を指定したファイルを移動。 C:\dev\java>dir package1 [Enter] ← パッケージ「package1」内を確認。 ドライブ C のボリューム ラベルは Local Disk です ボリューム シリアル番号は 001A-E4E3 です C:\dev\java\package1 のディレクトリ 2008/03/16 09:38 <DIR> . 2008/03/16 09:38 <DIR> .. 2008/03/16 09:29 161 Package1301.java 1 個のファイル 161 バイト 2 個のディレクトリ 52,261,765,120 バイトの空き領域 C:\dev\java>javac Sample1301.java [Enter] ← コンパイル(「Package1301.java」も一緒にコンパイルされます。) C:\dev\java>java Sample1301 [Enter] ← 実行。 使用したクラスは 「package1」パッケージ内の「Package1301」クラスです。
パッケージをインポート(import)することで、パッケージ名を指定せずにクラスやインタフェースを呼び出すことができるようになります。
パッケージ内のクラスやインタフェースをインポートするには、次の書式でソースファイルの先頭(パッケージ「package」指定がある場合はその次)に指定します。
import パッケージ名.クラス名; import パッケージ名.インタフェース名;
パッケージの指定「pakage」は複数指定することは出来ませんが、インポート「import」は複数記述することができます。
また次のようにファイル名の記述部分を「*」(アスタリスク)を指定する事で、パッケージ内の全てのファイルをインポートする事も可能です。
import パッケージ名.*;
上記サンプル(Sample1301.java)でインポートを使用すると次のようになります。
・サンプルソース(Sample1302.java)
import package1.Package1301; public class Sample1302 { public static void main(String[] args) { //「package1.Package1301」をインポートしているので次のようにクラス名のみで使用できます。 Package1301 pk = new Package1301(); System.out.println("使用したクラスは"); System.out.println(pk.getName()); } }
・実行結果
C:\dev\java>javac Sample1302.java [Enter] C:\dev\java>java Sample1302 [Enter] 使用したクラスは 「package1」パッケージ内の「Package1301」クラスです。
JAR (Java ARchive)を使用することで、パッケージに収められたファイル郡を圧縮ファイル(アーカイブ)として取り扱うことができます。JARの詳細についてはJDKドキュメントを参照してください。
JARファイルはjarコマンドで作成します。JARファイルを作成する一般的な使用方法は次のようになります。
jar cf JARファイル名.jar *.class
使用例として上記のパッケージ「package1」をJARファイルに変換します。
C:\dev\java>dir [Enter] ← パッケージのあるフォルダーへ移動して中身を確認。 ドライブ D のボリューム ラベルは Local Disk です ボリューム シリアル番号は 001A-E4E3 です C:\dev\java のディレクトリ 2008/03/16 09:38 <DIR> . 2008/03/16 09:38 <DIR> .. 2008/03/16 09:37 <DIR> package1 ← JARファイルにするパッケージ。 2008/03/16 09:37 538 Sample1301.class 2008/03/16 09:30 332 Sample1301.java 2008/03/16 09:40 538 Sample1302.class 2008/03/16 09:38 350 Sample1302.java 4 個のファイル 1,758 バイト 3 個のディレクトリ 52,261,765,120 バイトの空き領域 C:\dev\java>jar cf package1.jar package1 [Enter] ← パッケージのフォルダを指定してJARファイル「package1.jar」の作成。 C:\dev\java>dir [Enter] ← 実行後の中身を確認。 ドライブ C のボリューム ラベルは Local Disk です ボリューム シリアル番号は 001A-E4E3 です C:\dev\java のディレクトリ 2008/03/16 09:44 <DIR> . 2008/03/16 09:44 <DIR> .. 2008/03/16 09:37 <DIR> package1 2008/03/16 09:44 1,112 package1 ← JARファイル「package1.jar」ができています。 2008/03/16 09:37 538 Sample1301.class 2008/03/16 09:30 332 Sample1301.java 2008/03/16 09:40 538 Sample1302.class 2008/03/16 09:38 350 Sample1302.java 5 個のファイル 2,870 バイト 3 個のディレクトリ 52,261,756,928 バイトの空き領域
次のコマンドでJARファイルの中身を確認できます。
jar tvf JARファイル名.jar
作成したpackage1.jarの中身を確認します。
C:\dev\java>jar tvf package1.jar [Enter] 0 Sun Mar 16 09:44:14 JST 2008 META-INF/ 71 Sun Mar 16 09:44:14 JST 2008 META-INF/MANIFEST.MF 0 Sun Mar 16 09:37:22 JST 2008 package1/ 355 Sun Mar 16 09:37:22 JST 2008 package1/Package1301.class ← パッケージ及びクラスが確認できます。 161 Sun Mar 16 09:29:30 JST 2008 package1/Package1301.java
JARファイルは配置しただけではアクセスできません。クラスパスを設定する必要があります。尚、クラスパスについては下記を参照してください。
C:\dev\java>rmdir /S/Q package1 [Enter] ← package1フォルダを削除します。 C:\dev\java>dir [Enter] ← 中身を確認。 ドライブ C のボリューム ラベルは Local Disk です ボリューム シリアル番号は 001A-E4E3 です C:\dev\java のディレクトリ 2008/03/16 09:49 <DIR> . 2008/03/16 09:49 <DIR> .. 2008/03/16 09:44 1,112 package1.jar ← パッケージ「package1」はJARファイルのみ。 2008/03/16 09:37 538 Sample1301.class 2008/03/16 09:30 332 Sample1301.java 2008/03/16 09:40 538 Sample1302.class 2008/03/16 09:38 350 Sample1302.java 5 個のファイル 2,870 バイト 2 個のディレクトリ 52,261,756,928 バイトの空き領域 C:\dev\java>java Sample1301 [Enter] ← 実行するとパッケージ「package1」へのアクセスができずエラーが発生します。 Exception in thread "main" java.lang.NoClassDefFoundError: package1/Package1301 at Sample1301.main(Sample1301.java:4)
C:\dev\java>set classpath=.;c:\dev\java\package1.jar [Enter] ← カレントディレクトリ及びpackage1.jarに対してクラスパスを設定。 C:\dev\java>java Sample1301 [Enter] ← パッケージ「package1」へのアクセスができるようになり、正常に実行されます。 使用したクラスは 「package1」パッケージ内の「Package1301」クラスです。
上記ではクラス(.class)ファイルが保存されているフォルダー(カレントディレクトリ)にパッケージを作成して呼び出していましたが、「クラスパス」を指定することでパッケージをカレントディレクトリ以外にも配置することができます。「クラスパス」とはJVMにクラス(.class)ファイルの場所を知らせる仕組みのことです。
JVMは次の順番でクラス(.class)ファイルを探索します。
※1 クラスパスが設定されている場合にカレントディレクトを参照するにはカレントディレクトリ(「.」)を明示的に指定する必要がありますので注意してください。
次のコマンドによりクラスパスを設定することができます。
set CLASSPATH = クラスへのパス1;クラスへのパス2;... (Windowsの場合) setenv CLASSPATH クラスへのパス1:クラスへのパス2:... (Unixの場合)
また次のようにjavaコマンド実行時に指定することも可能です。
java -classpath クラスファイルへのパス
設定されているクラスパスの内容は次のコマンドで確認できます。
set CLASSPATH (Windowsの場合) env | grep CLASSPATH (Unixの場合)
パッケージを利用することでクラスの一意性は高まりますが、それでも完全に一意になることを保障するものではありません。そこで名前の一意性が高いドメイン名をパッケージ名としてよく用いられています。
例えば「itsenka.com」を使用した場合、次のようにドメインを逆さにしたパッケージ名が慣例となっています。
com.itsenka