Java超|import文の使い方

import は、別パッケージの戦士クラスを使いやすくする案内札。長い住所を毎回書かなくても、先に宣言しておけば、クラス名だけですっきり呼び出せます。

前回までに、異なるパッケージにあるクラスを使うときは、パッケージ名.クラス名 の形で指定することを学びました。

たとえば、pc パッケージにある SaiyanWarrior クラスを、pb パッケージのクラスから使う場合は、次のように書きます。

pc.SaiyanWarrior warrior1 = new pc.SaiyanWarrior();

この書き方は正しいです。
どのパッケージにある SaiyanWarrior クラスを使っているのかが、はっきり分かります。

ただし、同じクラスを何度も使う場合、毎回 pc.SaiyanWarrior と書くのは少し長く感じます。

ドラゴンボール風にたとえると、毎回「pc の棚にある SaiyanWarrior の巻物を使います」と、住所をすべて読み上げているようなものです。

そこで使うのが import 文 です。

import 文を使うと、別パッケージにあるクラスを、ファイルの先頭で「このクラスを使います」と先に宣言できます。
すると、プログラム本体ではパッケージ名を毎回書かずに、クラス名だけで使えるようになります。

import pc.SaiyanWarrior;

この1行を書いておけば、そのファイルの中では次のように書けます。

SaiyanWarrior warrior1 = new SaiyanWarrior();

つまり import 文は、別パッケージのクラスを自分のコード内で使いやすくするための仕組みです。

ドラゴンボール風に言えば、pc の棚にある SaiyanWarrior の巻物を使うことを、出撃前にあらかじめ申請しておくようなものです。
申請しておけば、任務中は SaiyanWarrior と短く呼べるようになります。

import文とは何か

import 文とは、別のパッケージにあるクラスを、現在のソースファイルで使いやすくするための宣言です。

基本の形は次のとおりです。

import パッケージ名.クラス名;

たとえば、pc パッケージにある SaiyanWarrior クラスを使いたい場合は、次のように書きます。

import pc.SaiyanWarrior;

これにより、そのソースファイルの中では SaiyanWarrior という短い名前でクラスを使えます。

書き方意味
pc.SaiyanWarriorpc パッケージにある SaiyanWarrior を住所つきで指定する
import pc.SaiyanWarrior;pc.SaiyanWarrior をこのファイルで使うことを先に宣言する
SaiyanWarriorimport 後に使える短いクラス名

ここで大切なのは、import はクラスをコピーするものではないという点です。
また、クラスの所属パッケージを変えるものでもありません。

pc.SaiyanWarrior は、import しても pc パッケージのクラスのままです。

import は、あくまで
このファイルでは pc.SaiyanWarrior を SaiyanWarrior と短く書けるようにする
ためのものです。

ドラゴンボール風に考える import のイメージ

ドラゴンボール風にたとえると、パッケージは巻物を整理する棚です。

Javaドラゴンボール風のイメージ
pc パッケージサイヤ人戦士情報を置いている棚
SaiyanWarrior クラスサイヤ人戦士の情報が書かれた巻物
pb パッケージ任務を実行する指令書の棚
Sample6 クラスSaiyanWarrior を使う任務指令書
import 文別の棚の巻物を使うための事前申請

pb パッケージの Sample6 から、pc パッケージの SaiyanWarrior を使う場合、何も準備しなければ、pc.SaiyanWarrior と住所つきで書く必要があります。

しかし、ファイルの先頭で次のように書いておけば、

import pc.SaiyanWarrior;

main メソッドの中では、SaiyanWarrior と短く書けます。

これは、任務の最初に「pc の棚にある SaiyanWarrior の巻物を使います」と申請しておくようなものです。
そのあとは、いちいち pc の棚にあると説明しなくても、SaiyanWarrior だけで通じるようになります。

importを使わない場合

まず、import を使わない場合を確認します。

異なるパッケージのクラスを使う場合、パッケージ名を含めてクラス名を書く必要があります。

pc.SaiyanWarrior warrior1 = new pc.SaiyanWarrior();

この書き方では、型の部分にも pc.SaiyanWarrior、new の部分にも pc.SaiyanWarrior と書いています。

部分意味
pc.SaiyanWarrior warrior1warrior1 は pc パッケージの SaiyanWarrior 型
new pc.SaiyanWarrior()pc パッケージの SaiyanWarrior オブジェクトを作成

この書き方は、どのパッケージのクラスを使っているかが明確です。

ただし、同じクラスを何度も使う場合、毎回 pc.SaiyanWarrior と書くことになります。

import を使わない場合特徴
pc.SaiyanWarrior と毎回書くどのクラスかは明確
記述が長くなる何度も出ると読みづらくなる
書き間違いが起こりやすいパッケージ名も毎回書くため

ドラゴンボール風に言えば、毎回「pc の棚にある SaiyanWarrior の巻物」と正式名称で呼び続けるようなものです。

importを使うとどう変わるのか

import を使うと、ファイルの先頭で使いたいクラスを指定できます。

import pc.SaiyanWarrior;

この1行を書いておけば、main メソッドの中では次のように短く書けます。

SaiyanWarrior warrior1 = new SaiyanWarrior();

import を使う前後を比べると、違いが分かりやすいです。

比較書き方
import なしpc.SaiyanWarrior warrior1 = new pc.SaiyanWarrior();
import ありSaiyanWarrior warrior1 = new SaiyanWarrior();

import を使うと、コードの中で注目したい処理が見えやすくなります。

SaiyanWarrior オブジェクトを作る。
show() を呼ぶ。

この流れがすっと読めるようになります。

import の効果内容
記述が短くなるパッケージ名を毎回書かなくてよい
読みやすくなる処理の流れに集中しやすい
管理しやすくなる使う外部クラスを先頭で確認できる
書き間違いを減らしやすい長いパッケージ名を何度も書かなくてよい

図:import は別パッケージのクラスを使う案内札

この図が示していること

この図では、pb パッケージの Sample6.java から、pc パッケージの SaiyanWarrior クラスを import して使う流れを表しています。

pc パッケージには SaiyanWarrior.java があります。
SaiyanWarrior クラスは public なので、別パッケージから利用できます。

pb パッケージには Sample6.java があります。
Sample6.java の先頭で import pc.SaiyanWarrior; と書くことで、main メソッドの中では SaiyanWarrior と短く書けるようになります。

要素役割
pc.SaiyanWarriorpc パッケージにある利用されるクラス
import pc.SaiyanWarrior;Sample6.java で SaiyanWarrior を使うための宣言
SaiyanWarrior warrior1 = new SaiyanWarrior();import 後の短い書き方
pb.Sample6実行するクラス

この図から分かることは、import はクラスの所属を変えるのではなく、別パッケージのクラスを使いやすくするための仕組みだということです。

import文を書く場所

import 文は、ソースファイルの先頭付近に書きます。

ただし、package 文がある場合は、package 文のあとに import 文を書きます。

今回の Sample6.java では、次の順番になります。

順番書くもの役割
1package pb;このファイルのクラスが pb パッケージに属することを示す
2import pc.SaiyanWarrior;pc パッケージの SaiyanWarrior を使うことを示す
3class Sample6実際のクラス定義を書く

コードの形で見ると、次のようになります。

package pb;

import pc.SaiyanWarrior;

class Sample6
{
}

package 文より前に import 文を書くことはできません。
また、クラス定義の途中に import 文を書くこともできません。

書く位置正しいか
package 文のあと正しい
package 文の前正しくない
class の中正しくない
メソッドの中正しくない

ドラゴンボール風にたとえると、まず「この巻物は pb の棚に置く」と所属を決めます。
そのあとで「pc の棚にある SaiyanWarrior の巻物を使います」と申請します。
そして最後に、任務の内容を書き始めるイメージです。

package文とimport文の違い

package 文と import 文は、どちらもファイルの先頭付近に書くため、少し混同しやすいです。

しかし、役割はまったく違います。

役割ドラゴンボール風のイメージ
package 文自分のクラスがどのパッケージに属するかを決めるこの巻物をどの棚に置くか決める
import 文別パッケージのクラスを使いやすくする別の棚の巻物を使う申請をする

今回なら、Sample6 クラスは pb パッケージに属します。

package pb;

一方、SaiyanWarrior クラスは pc パッケージにあります。

import pc.SaiyanWarrior;

つまり、次の関係です。

クラス所属
Sample6pb
SaiyanWarriorpc

import pc.SaiyanWarrior; と書いても、SaiyanWarrior が pb パッケージに移動するわけではありません。

ここはとても大切です。

importしてもクラスの所属は変わらない

import を書くと、別パッケージのクラスが自分のパッケージに入ってきたように感じるかもしれません。

しかし、実際にはそうではありません。

SaiyanWarrior クラスは、import しても pc パッケージに属したままです。
Sample6 クラスは、pb パッケージに属したままです。

クラス所属パッケージimport 後
SaiyanWarriorpcpc のクラスのまま
Sample6pbpb のクラスのまま

import は、クラスの所属を変える仕組みではありません。

import は、別パッケージのクラスを、今書いているファイルの中で短く使えるようにする仕組みです。

ドラゴンボール風にたとえると、pc の棚にある巻物を pb の棚へ移動するわけではありません。
pb の任務指令書から、その巻物を参照しやすくしているだけです。

今回の例で使うファイル構成

今回は、pb パッケージの Sample6 クラスから、pc パッケージの SaiyanWarrior クラスを使います。

フォルダ構成は次のようになります。

C:\Java\13
        ├─ pb
        │  └─ Sample6.java
        └─ pc
           └─ SaiyanWarrior.java
ファイルパッケージ役割
pb\Sample6.javapbmain メソッドを持つ実行用クラス
pc\SaiyanWarrior.javapcサイヤ人戦士の情報を表すクラス

SaiyanWarrior クラスは、別パッケージから使われるため public にします。

public class SaiyanWarrior

Sample6.java 側では、ファイルの先頭で import します。

import pc.SaiyanWarrior;

これにより、Sample6.java の中では SaiyanWarrior と短く書けます。

ファイル名:Sample6.java

package pb;

import pc.SaiyanWarrior;

class Sample6
{
    public static void main(String[] args)
    {
        SaiyanWarrior warrior1 = new SaiyanWarrior();
        warrior1.show();
    }
}

ファイル名:SaiyanWarrior.java

package pc;

// サイヤ人戦士クラス
public class SaiyanWarrior
{
    private String name;
    private String style;

    public SaiyanWarrior()
    {
        name = "未登録";
        style = "流派未設定";
        System.out.println("サイヤ人戦士を準備しました。");
    }

    public void setWarrior(String n, String s)
    {
        name = n;
        style = s;
        System.out.println("戦士名を" + name + "、流派を" + style + "にしました。");
    }

    public void show()
    {
        System.out.println("戦士名は" + name + "です。");
        System.out.println("流派は" + style + "です。");
    }
}

実行結果

サイヤ人戦士を準備しました。
戦士名は未登録です。
流派は流派未設定です。

この実行結果では、Sample6 から SaiyanWarrior オブジェクトを作成し、show() を呼び出しています。

SaiyanWarrior のコンストラクタでは、name に 未登録、style に 流派未設定 を設定しています。
そのため、show() を呼び出すと、初期状態の戦士情報が表示されます。

Sample6.javaの中心になる部分

このプログラムで特に大切なのは、次の3つです。

package pb;

import pc.SaiyanWarrior;

SaiyanWarrior warrior1 = new SaiyanWarrior();

まず、package pb; によって、Sample6 クラスは pb パッケージに属します。

次に、import pc.SaiyanWarrior; によって、pc パッケージの SaiyanWarrior クラスをこのファイルで使いやすくしています。

そして、main メソッドの中では、SaiyanWarrior とクラス名だけで書いています。

コード意味
package pb;Sample6 は pb パッケージに属する
import pc.SaiyanWarrior;pc パッケージの SaiyanWarrior を使う
SaiyanWarrior warrior1 = new SaiyanWarrior();import 済みなのでクラス名だけで使える
warrior1.show();SaiyanWarrior オブジェクトの情報を表示する

import がなければ、main メソッドの中は次のように書く必要があります。

pc.SaiyanWarrior warrior1 = new pc.SaiyanWarrior();

import があるため、次のようにすっきり書けます。

SaiyanWarrior warrior1 = new SaiyanWarrior();

SaiyanWarriorクラスはpublicである必要がある

異なるパッケージからクラスを使う場合、利用される側のクラスは public である必要があります。

今回、Sample6 は pb パッケージにあります。
SaiyanWarrior は pc パッケージにあります。

つまり、Sample6 から見ると SaiyanWarrior は別パッケージのクラスです。

そのため、SaiyanWarrior クラスは次のように public にします。

public class SaiyanWarrior
クラスの指定別パッケージから利用できるか
class SaiyanWarrior基本的に同じパッケージ内からのみ
public class SaiyanWarrior別パッケージからも利用できる

また、SaiyanWarrior のコンストラクタや show() も public にしています。

public SaiyanWarrior()

public void show()

クラスが public でも、コンストラクタやメソッドが外部から使えない範囲だと、別パッケージから十分に利用できません。

今回のように、別パッケージからオブジェクトを作って show() を呼び出すなら、コンストラクタと show() も public にしておく必要があります。

要素修飾子理由
SaiyanWarrior クラスpublicpb パッケージから使うため
SaiyanWarrior() コンストラクタpublicpb パッケージから new するため
show() メソッドpublicpb パッケージから呼び出すため
name フィールドprivate外部から直接変更させないため
style フィールドprivate外部から直接変更させないため

ドラゴンボール風にたとえると、SaiyanWarrior の巻物自体は他の棚から閲覧可能にします。
ただし、name や style のような内部情報は、直接書き換えられないように守っています。

図:package文とimport文の役割の違い

この図が示していること

この図では、package 文と import 文の役割の違いを表しています。

package pb; は、Sample6 クラスが pb パッケージに属することを示します。
つまり、Sample6 自身の住所を決める文です。

一方、import pc.SaiyanWarrior; は、pc パッケージにある SaiyanWarrior クラスを、このファイルで使いやすくするための文です。

役割今回の例
package 文自分の所属を決めるSample6 は pb パッケージ
import 文使いたい外部クラスを指定するpc.SaiyanWarrior を使いやすくする

この図から分かることは、package と import はどちらも先頭付近に書きますが、意味はまったく違うということです。

package は自分の住所を決めるものです。
import は使いたい相手への案内札です。

importを使った場合のコンパイル

作業中フォルダが C:\Java\13 の場合、フォルダ構成は次のようになります。

C:\Java\13
        ├─ pb
        │  └─ Sample6.java
        └─ pc
           └─ SaiyanWarrior.java

コンパイルは、作業中フォルダから行います。

PS C:\Java\13>javac pb\Sample6.java

Sample6.java は pc.SaiyanWarrior を import しています。

import pc.SaiyanWarrior;

そのため、pc フォルダの中に SaiyanWarrior.java があり、SaiyanWarrior クラスが public であれば、必要に応じてコンパイルされます。

コンパイル後は、次のようになります。

C:\Java\13
        ├─ pb
        │  ├─ Sample6.java
        │  └─ Sample6.class
        └─ pc
           ├─ SaiyanWarrior.java
           └─ SaiyanWarrior.class
ソースファイルコンパイル後
pb\Sample6.javapb\Sample6.class
pc\SaiyanWarrior.javapc\SaiyanWarrior.class

importを使った場合の実行

実行するときは、main メソッドを持つクラスを指定します。

今回、main メソッドを持つのは Sample6 クラスです。

Sample6 は pb パッケージに属しています。

そのため、実行時は次のように書きます。

PS C:\Java\13>java pb.Sample6
コマンド意味
java pb.Sample6pb パッケージの Sample6 クラスを実行する

ここで java Sample6 ではありません。

Sample6 は pb パッケージに属するため、pb.Sample6 と住所つきで指定します。

import pc.SaiyanWarrior; を書いていても、Sample6 の所属は pb のままです。
そのため、実行時には pb.Sample6 と書きます。

図:importを使ったコンパイルと実行の流れ

この図が示していること

この図では、import を使った場合のコンパイルと実行の流れを表しています。

Sample6.java は pb パッケージに属しています。
その中で import pc.SaiyanWarrior; と書くことで、pc パッケージの SaiyanWarrior を短い名前で使えるようにしています。

コンパイルは作業中フォルダから次のように行います。

PS C:\Java\13>javac pb\Sample6.java

実行するときは、main メソッドを持つ Sample6 をパッケージ名付きで指定します。

PS C:\Java\13>java pb.Sample6
操作指定
コンパイルjavac pb\Sample6.java
実行java pb.Sample6

この図から分かることは、import を使っても Sample6 の所属は pb のままであり、実行時には pb.Sample6 と指定する必要があるということです。

importを使うときに気をつけたいこと

import は便利ですが、いくつか注意点があります。

注意点内容
利用されるクラスは public が必要別パッケージから使えるようにする必要がある
import は package 文のあとに書く書く順番を守る
import しても所属は変わらないpc.SaiyanWarrior は pc のクラスのまま
同名クラスがある場合は注意どのクラスを使うか分かりにくくなることがある
import はコードを短くするが、意味を消すわけではない先頭の import を見れば利用クラスが分かる

特に、同じ名前のクラスが複数ある場合は注意が必要です。

たとえば、pa.SaiyanWarrior と pc.SaiyanWarrior の両方がある場合、どちらを import するかによって、SaiyanWarrior と書いたときに指すクラスが変わります。

クラス意味
pa.SaiyanWarriorpa パッケージの SaiyanWarrior
pc.SaiyanWarriorpc パッケージの SaiyanWarrior

このような場合は、読みやすさのために、あえて pc.SaiyanWarrior のようにパッケージ名付きで書くこともあります。

importとパッケージ名付き記述の使い分け

import を使う書き方と、パッケージ名付きで書く方法は、どちらも正しい書き方です。

書き方特徴
パッケージ名付きで書くpc.SaiyanWarrior warrior1 = new pc.SaiyanWarrior();どのクラスか明確
import して短く書くSaiyanWarrior warrior1 = new SaiyanWarrior();コードがすっきりする

同じクラスを1回だけ使うなら、パッケージ名付きで書いても大きな問題はありません。

しかし、何度も同じクラスを使う場合は、import を使ったほうがコードが読みやすくなります。

場面向いている書き方
どのパッケージか明確に見せたいパッケージ名付き
同じクラスを何度も使うimport
同名クラスが複数あって紛らわしいパッケージ名付き
通常の実用的なコードimport を使うことが多い

import は、コードを短くするだけではなく、処理本体を読みやすくするための仕組みでもあります。

importで大切な感覚

import 文で大切なのは、次の感覚です。

考え方内容
package は自分の住所Sample6 は pb パッケージに属する
import は相手への案内札pc.SaiyanWarrior を使いやすくする
import 後は短く書けるSaiyanWarrior とだけ書ける
所属は変わらないSaiyanWarrior は pc パッケージのクラスのまま
public は必要別パッケージから使うには公開されている必要がある

ドラゴンボール風にたとえると、Sample6 は pb の任務指令書です。
SaiyanWarrior は pc の戦士名簿です。

import pc.SaiyanWarrior; は、pb の任務指令書から pc の戦士名簿を使いやすくするための案内札です。

案内札があるから、任務本文では SaiyanWarrior と短く呼べます。
ただし、戦士名簿そのものは pc の棚に置かれたままです。

この感覚がつかめると、import 文はとても自然に理解できます。