こんにちは。ECF Techブログ
担当 Michiharu.Tです。
Javaプログラミング入門記事の第15章をお送りいたします。
第15章のテーマは「パッケージ」です。
本連載の初回および章立ての一覧については下記のリンクから確認できます。
本章では、複数のクラスをまとめるためのしくみであるパッケージについて説明します。
15-1 パッケージとは
パッケージはクラスを整理整頓するためのフォルダのようなものです。ここでは次のような構成のプログラムを動作させる過程をご紹介しながら、パッケージの使い方について学びます。
15-1-1 パッケージ宣言
パッケージを利用するためには、パッケージ宣言を行う必要があります。パッケージ宣言の記述例は次のとおりです。
package パッケージ名.パッケージ名2; //・・・以降、クラス定義など
- パッケージ宣言は、クラスやインタフェースを定義したファイルの先頭に記述する必要があります。
- 複数のパッケージ名を
.
でつなげて書くことで、パッケージを入れ子にすることができます。
それでは実際に、パッケージ宣言を使ってMainクラスを定義してみましょう。プログラム例を示します。
プログラム例(Main.java)
package myapp; public class Main{ public static void main(String[] args){ System.out.println("こんにちは"); } }
1行目の記述によりMainクラスをmyappというパッケージに所属させることができます。現時点での構成イメージは次のようになります。
15-1-2 パッケージに所属したクラスの利用
次に作成したMain.javaをコンパイル・実行させてみましょう。これまでどおり、Main.javaのあるフォルダをカレントフォルダとして、コマンドプロンプトから次のコマンドを実行します。
> javac Main.java
コンパイルが成功したら実行してみましょう。次のようなエラーが表示されます。
> java Main エラー: メイン・クラスMainを検出およびロードできませんでした 原因: java.lang.NoClassDefFoundError: Main (wrong name: myapp/Main)
パッケージに所属したクラスを動作させるには、次の2つのことを行う必要があります。
- クラスファイルを適切なフォルダに配置する。
- 完全修飾名を使って実行する。
1つずつ確認しましょう。まずは任意のフォルダを作成します(以降、基準フォルダと呼びます)。クラスファイルの配置場所は、この基準フォルダからパッケージ名をたどるように決まります。今回、Main.javaはmyappパッケージに所属させていますので、基準フォルダ内にmyappフォルダを作成し、その中にMain.classのファイルを保存します。下図はsrcという名前のフォルダを基準フォルダとした場合の配置です。
次に実行です。パッケージに所属したクラスを実行させるには、実行時のコマンドで完全修飾名を使用する必要があります。完全修飾名はパッケージ名を含めたクラスのフルネームのようなもので、次のように記述します。
パッケージ名.クラス名
Mainクラスはmyappパッケージに所属しているため、myapp.Main
が完全修飾名となります。
では、実際に動作を確認してみましょう。コマンドプロンプトを起動し、基準フォルダに移動します。その上で次のコマンドでMainクラスを実行します。
> java myapp.Main こんにちは
正しく実行することができました。
15-1-3 -dオプション
ここまでパッケージを利用した上での実際の動作手順をご紹介しましたが、1つ1つのファイルを適切なフォルダを作って手作業で配置するのは大変な作業です。このような場合に便利なのがjavacコマンドの -dオプション です。使用例は次のようになります。
javac -d 出力先フォルダ *.java
上記のコマンドを実行すると、カレントフォルダにあるすべてのJavaファイルをコンパイルし、出力先フォルダ内にパッケージ宣言に合わせて適切に配置をしてくれます。
15-1-2で作成したフォルダやクラスファイルを1度削除し、Main.javaがあるカレントフォルダで次のように実行してみましょう。
javac -d . *.java
-dオプションで指定した.
はカレントフォルダを意味します。これにより、カレントフォルダを基準フォルダとしてクラスファイルが配置されるように動作します。実行するとカレントフォルダ内にmyappフォルダが作成され、Main.classが自動的に配置されます。
続けて次のコマンドを実行すると、プログラムを実行することができます。
> java myapp.Main こんにちは
15-2 別パッケージ内のクラス利用
では次に別のパッケージ内にUserクラスを定義し、Main.javaから利用するプログラムをご紹介します。まずはUserクラスのプログラムを示します。
プログラム例(User.java)
package myapp.util; public class User{ private String sei; private String mei; public User(String sei, String mei){ this.sei = sei; this.mei = mei; } public void introduce(){ System.out.println(sei + mei + "です。"); } }
フィールドに姓と名を持つシンプルなクラスです。パッケージ宣言はmyapp.util
としていますので、パッケージの構成を図にすると、次のようになります。
図を見ると
- Main.javaはmyappパッケージに配置
- User.javaはmyapp.utilパッケージに配置
されていることがわかります。
次に、MainクラスからUserクラスにアクセスするプログラムを作成します。Main.javaをUserクラスを利用する形に修正します。
プログラム例(Main.java)
package myapp; public class Main{ public static void main(String[] args){ myapp.util.User user = new myapp.util.User("山田","太郎"); user.introduce(); } }
解説
パッケージに属しているクラスを利用する際は、パッケージ名を含めた完全修飾名を使用する必要があります。Userクラスはmyapp.utilパッケージに属しているため、3行目の変数宣言やインスタンスの生成時にmyapp.util.User
としています。
それでは2つのファイルをコンパイルし、動作確認をしてみましょう。Main.javaとUser.javaを同一フォルダに保存し、同フォルダをカレントフォルダとした上で下記のコマンドを実行します。
javac -d . User.java Main.java
つづけて、次のように実行します。
java myapp.Main
実行結果
山田太郎です。
実行したフォルダ内を見てみると、クラスファイルが次のように配置されていることが確認できます。
15-2-1 import宣言
別パッケージに属するクラスを利用する例を示しましたが、利用のたびに毎回完全修飾名を記述するのは記述量も多くなり、ミスが増える原因となります。import宣言を使うと完全修飾名の記述を1回だけで済ませられるようになります。import宣言の文法は次のようになります。
import クラスの完全修飾名;
15-2で登場したMain.javaをimport宣言を使って書き換えたプログラム例を示します。
プログラム例(Main.java)
import myapp.util.User; public class Main{ public static void main(String[] args){ User user = new User("山田","太郎"); user.introduce(); } }
実行結果
山田太郎です。
解説
1行目がimport宣言です。myapp.utilパッケージにあるUserクラスを使用したいので、あらかじめimport宣言でUserクラスの完全修飾名を記述しています。これにより「以降のプログラム中にUser
の表記があった場合はmyapp.util.User
とみなしてください。」とコンパイラに伝えています。
上記のようにパッケージに含まれるクラスを利用する際は、通常import宣言をして利用します。ですが、次の2つに該当するクラスについてはimport宣言をしなくてもこれまで同様にクラス名だけで利用することができます。
- 同一パッケージに含まれるクラス
- java.langパッケージに含まれるクラス
※java.langパッケージについては次節で説明します。
15-3 Java API
Javaのプログラムを作成するためにインストールしたJDKには、あらかじめ数多くのクラスが同梱されています。これらはクラスライブラリ、またはAPI(Application Programming Interface)と呼ばれています。私たちJavaのプログラマは、このAPIに含まれる様々なクラスを利用することで、効率的にプログラムを書くことができます。
15-3-1 Stringクラス
例えばAPIに含まれる代表的なクラスとしてStringクラスがあります。Stringはこれまで単に文字列の型として利用してきましたが、StringクラスはAPIに含まれる多機能なクラスで、次のようなメソッドを利用することができます。
定義 | 動作概要 |
---|---|
public int length() | この文字列の文字数を返します。 |
public char charAt(int index) | この文字列のindex番目の文字を返します。(indexは0から開始) |
public String concat(String str) | この文字列に、文字列strを結合した新しい文字列を返します。 |
上記のメソッドを利用したプログラム例を示します。
プログラム例(Main.java)
public class Main{ public static void main(String[] args){ String str = "Hello"; System.out.println(str.length()); System.out.println(str.charAt(1)); System.out.println(str.concat("World")); } }
実行結果
5 e HelloWorld
解説
str.length()
は変数strが指す文字列の長さを返します。strはHello
なので5文字です。したがって、5が戻り値として返され、表示されています。str.charAt(1)
は変数strが指す文字列の1番目の文字を返します。最初を0と数えるので、1番目はe
です。したがって、eが戻り値として返され、表示されています。str.concat("World")
は変数strが指す文字列にWorld
の文字列を結合した新しい文字列を返します。したがって、HelloWorld
が戻り値として返され、表示されています。
15-3-2 APIリファレンス
APIリファレンスは、JDKにあらかじめ含まれているAPIの使い方を示した公式のマニュアルです。バージョンごとにインターネット上で閲覧することができ、JDK Version18のマニュアルであれば、下記のURLから確認できます。
APIリファレンスの使い方
APIリファレンスの使い方は大きく
- 見たいクラスやインタフェースを検索する
- 検索したクラスやインタフェースの詳細を見る
です。サイトに遷移したら、右上の検索ウィンドウから詳細を見たいクラス名を入力します。候補が表示されますので、該当するクラスを選択します(下図)。
各クラス等の詳細ページに遷移します。詳細ページは次のような構成になっていますので、各概要から見たいメソッドなどを探して、詳細を確認しましょう。