型インポート宣言

パッケージ - rderaログでパッケージについて、サラッと学んだ。
次は、パッケージに関連して型インポート宣言について。

型インポート宣言とは?

パッケージ - rderaログではパッケージに所属するクラスを呼ぶのには、完全限定名と単純名があることを学びました。
でも、完全限定名は長い。短くしたい。楽をしたい。
単純名で呼びたい。
それを可能にするのが、型インポート宣言です。

型インポート宣言の具体例

パッケージ - rderaログで例として挙げた、パッケージaに所属するクラスDataを単純名で呼びたい場合は以下の記述をソースプログラムの冒頭に記述します。

import a.Data;

これで、単純名で呼ぶことができるようになります。
つまり、

import 完全限定名;

の記述をソースプログラムの冒頭に記述します。

他にも具体例を挙げます。
javaのプログラムでよく出てくる、パッケージjava.utilに属するクラスScannerを考えます。これを単純名で呼びたい場合は以下のimport文を記述します。

import java.util.Scanner;

この記述をすることにより、以下のように単純名でクラスを呼ぶことができます。

Scanner stdIn = new Scanner(System.in);

ちなみにimport文を記述しないと以下のように完全限定名で呼ぶことになります。

java.util.Scanner stdIn = new java.util.Scanner(System.in);

実は2種類ある。

型インポート宣言の宣言方法は2種類あります。

単一型インポート宣言
オンデマンド型インポート宣言

です。

単一型インポート宣言

今まで書いてきたimport文がこれです。
前にも書いて繰り返しになりますが

import 完全限定名;

という書式です。
ちなみに具体例

import java.util.Scanner;

オンデマンド型インポート宣言

まず、書式から

import パッケージ名.*;

この宣言によって、パッケージ名に所属するクラスを単純名で利用できるようになります。
具体例を見ていきます。

import java.util.*;

このオンデマンド型インポート宣言によりjava.utilパッケージに属するクラスを単純名で利用できるようになります。クラスRandomとクラスScannerを使いたい場合は以下のように単純名で呼べます。

Random rand = new Random();
Scanner stdIn = new Scanner(System.in);

ちなみに単一型インポート宣言は以下のようになります。

import java.util.Random;
import java.util.Scanner;

オンデマンド型インポート宣言の注意事項

オンデマンド型インポート宣言では単一型インポート宣言に比べてimport文を単純にすることができます。パッケージjava.utilに属するクラスRandomとクラスScannerを単純名で使いたい場合を考えてみましょう。

//単一型インポート宣言
import java.util.Random;
import java.util.Scanner;
//オンデマンド型インポート宣言
import java.util.*;

見ての通り、オンデマンド型インポート宣言は楽です。
しかし、楽あれば苦あり。メリットがあるものにはデメリットが存在するものです。
オンデマンド型インポート宣言には注意しなければならないことがあります。


パッケージaとパッケージbに所属するクラスTestを単純名で利用しようとして以下のようなオンデマンド型インポート宣言をするとエラーになります。

import a.*;
import b.*;
.....
Test test = new Test(); // エラー

これは、プログラムにどちらのパッケージのクラスTestを使うか伝えていないからです。
以下のようにすると、エラーは出ません。しかし、完全修飾名で呼ぶことになります。

import a.*;
import b.*;
.....
a.Test test = new a.Test();

このことから学べるのは、オンデマンド型インポート宣言を多用するべきではないということです。
なるべく、単一型インポート宣言を利用し、プログラムにどのパッケージに所属するクラスを利用するのか伝える必要があります。



階層化されたパッケージに属するクラスを単純名で呼ぶことを考えます。
例えば、パッケージaの中のパッケージbに属するTestを単純名で呼ぶことを考えます。

import a.*;
.....
Test test = new Test(); // エラー

エラーになります。

import a.b.*;
.....
Test test = new Test(); // OK

こっちは大丈夫です。
階層化しているパッケージに属するクラスを呼ぶ場合、import文の宣言に気をつける必要があります。