Engineering Note

プログラミングなどの技術的なメモ

Java入門 パッケージの利用

java

本記事は、Javaを一から学んでいく際の学習メモとして書かれています。

主にインプレスから出版されている「スッキリわかるJava入門 第2版 (スッキリシリーズ)」の内容に沿ったかたちで学習していきます。

今回は、Javaのパッケージの利用について学んでいきます。

  

 

クラスファイルの分割

前回までは、同一のクラスファイル内にクラスメソッドとそれを呼び出すメインメソッドを定義しました。

 

しかし、クラスメソッドが増えてきた場合、一つのファイルに記述することは、同時に修正を加えたりするのが難しくなり、またソースコードの可動性の低下につながります。

 

そのため、メインメソッドとクラスメソッドを分割し、以下のように管理します。

 

// MyMath.java
public class MyMath{
    public static int abs(int n){
        return n > 0 ? n : -n; 
    }
}

 

// Main.java
public class Main{
    public static void main(String[] args) {
        System.out.println(MyMath.abs(-1));
    }
}

 

上記をコンパイルし、実行してみます。

 

 > javac Main.java
 > java Main
 1

 

abs()メソッドはstaticメソッドとなっているので、「クラス名.メソッド名()」の形でMainクラスから呼び出すことができます。

 

パッケージの利用

前述のようにメインメソッドとクラスメソッドを分割して管理することで、全体がすっきりとしますが、クラスファイルが増えすぎると、さらに分類および管理が必要になります。

その場合に用意されているものがパッケージと呼ばれる仕組みになります。

まず、パッケージに所属させるためにはソースコードの先頭にpackage文を記述する必要があります。

 

// MyMath.java
package math;  // パッケージ文
public class MyMath{
    public static int abs(int n){
        return n > 0 ? n : -n;
    }
}

 

// Main.java
public class Main{
    public static void main(String[] args) {
        System.out.println(math.MyMath.abs(-1));
    }
}

 

上記のMyMathクラスでは、ソースコードの先頭に「package パッケージ名;」を記述し、Mainクラスからは「パッケージ名.クラス名.メソッド名()」の形で呼び出すことができます。

 

なお、パッケージ文を記述した場合は、パッケージ名のディレクトリを作成し、その直下に格納する必要があります。

 

fig1. mathパッケージのディレクトリ構造

fig1. mathパッケージのディレクトリ構造

 

上記をコンパイルし、実行してみます。

 

 src> javac Main.java
 src> java Main
 1

 

なお、上記のMainクラスでは、package文の記述がありません。

このように、どのパッケージにも所属していことをデフォルトパッケージと呼びます。

 

Mainクラスはデフォルトパッケージに所属していますが、別のmainパッケージに所属させた場合に、abs()メソッドを呼び出すにはどうすれば良いでしょうか。

 

fig2. mainパッケージのディレクトリ構造

fig2. mainパッケージのディレクトリ構造

 

その場合は「パッケージ名.クラス名.メソッド名()」と記述することで呼び出すことができます。

このような記述方法を完全限定クラス名(full qualified class name: FQCNと呼びます。

 

// Main.java
package main;
public class Main{ 
    public static void main(String[] args){ 
        System.out.println(math.MyMath.abs(-1)); 
    }
}

 

クラスローダーとクラスパス

Javaでは、適切なクラスをロードするためにクラスローダーと呼ばれるものがあります。
クラスローダーは指定されたクラスパスからファイルを検索し、ロードします。

なお、javacコマンドでコンパイルする際は、コマンドプロンプトのカレントディレクトリがクラスパスになります。
クラスパスを指定してコンパイルする際は、以下のようにクラスパスオプションを指定します。 

 

 > javac -classpath="クラスパス"

 

それでは、上述のmainパッケージのMain.javaコンパイルしてみます。

コンパイルするには、コマンドプロンプトのカレントディレクトリをクラスパスのディレクトリへ移動させ(もしくはクラスパスを指定する)、javacコマンドを実行します。

 

 src> javac main\Main.java

 

プログラムを実行するには、「java パッケージ名.実行ファイル名」のような形で実行します。

 

 

 src> java main.Main
 1

 

import文の利用

import文を利用することにより、パッケージ名の入力を省略することが可能となります。

 

// Main.java
package main;
import math.MyMath; // mathパッケージのMyMathクラスをインポート
public class Main{ 
    public static void main(String[] args){ 
        System.out.println(MyMath.abs(-1)); 
    }
}

 

なお、パッケージにあるクラスをすべてインポートする場合は、ワイルドカードを使用することで記述が楽になります。

 

import math.*;

 

名前空間

パッケージ名には、すでに使われているパッケージ名を使用することは原則としてできず、同じパッケージ名を作成してしまうことを名前衝突と呼びます。

このような名前衝突を避けるために、所有しているインターネットドメイン名を逆順(ルートから)にしたものをパッケージ名として利用する方法があります。

インターネットドメイン名は重複が許されず、ユニーク(一意)であるため、名前衝突が起きることはありません。

 

例:
ドメイン名 :hoge.jp
パッケージ名:jp.hoge

 

最後に

今回はJavaのパッケージについて、基本的なルールを学びました。

今回で基本的なルールについては学んだので、次回からはオブジェクト指向について学んでいきます。

 

参考書籍

スッキリわかるJava入門 第2版 (スッキリシリーズ)