Corredor

ウェブ、プログラミングの勉強メモ。

Java の import しなくても良い理由がイマイチ分かってなかった

Java を会社の新人研修で勉強した時に疑問に思って、講師に聞いてみたら「確かに不思議ですね、持ち帰り調べてみます」と言われて、後日答えを聞いたのに細かいことを忘れてしまってまた気になってるヤツ。

例えば、以下のようなコード。Mather と Pattern を import している。

import java.util.regex.Matcher; // Matcher クラスを import
import java.util.regex.Pattern;

public class ImportTest {
  public static void main(String[] args) {
    String input = "abcdef";
    String regrex = "abc";
    
    // Matcher 型の変数
    Matcher matcher = Pattern.compile(regrex).matcher(input);
    
    if(matcher.find()) {
      System.out.println("マッチ!");
    }
    else {
      System.out.println("マッチせず");
    }
  }
}

次に、Matcher matcher = の行を if 文の中に直接書いて、Matcher 型の変数を作らないで書いたパターン。

import java.util.regex.Pattern;  // Matcher の import なし

public class ImportTest {
  public static void main(String[] args) {
    String input = "abcdef";
    String regrex = "abc";
    
    // 変数 matcher を作らずに記述
    if(Pattern.compile(regrex).matcher(input).find()) {
      System.out.println("マッチ!");
    }
    else {
      System.out.println("マッチせず");
    }
  }
}

その型の変数がクラス中に1回も登場しないと、上記の Matcher クラスのように、import 文が不要になる。

なぜこの import 文が不要になるのか、その仕組みがイマイチ理解できていなかった。

ちなみに、Pattern クラス内では Matcher クラスを import している。Matcher クラスは Pattern クラス内で import されてるから要らなくなるのかな?と思ったけど、そうすると Matcher 型のオブジェクトを宣言するパターンでは import が必要になる理由が分からない。

…と思って調べてみた。

  • 参考:importとは:SJC-P対策Java用語集

    importを利用すると、特定の パッケージ内のクラスまたは インタフェースを、 完全限定名 で指定しなくても呼び出せるようにできます。

  • 参考:Javaパッケージ メモ(Hishidama's Java Package Memo)

    パッケージ名を付けて指定したクラス名の書き方のことを、完全修飾クラス名(Fully Qualified Class Name:FQCN)あるいは完全限定名(fully qualified name:FQN)と呼ぶ。

import とは何ぞや、ってことがどうも間違ってたようだ。import 文によってそのクラスを読み込まないとそのクラスのメソッドが使えなかったりするもんだと思ってたが、import とはそういう意味ではなく、単純に「パッケージ込みの長ったらしいクラス名を省略して書けるようにするためのもの」でしかない様子。

つまり以下のように完全限定名を使って書いてやれば、import 文は一切不要なのだ。

public class ImportTest {
  public static void main(String[] args) {
    String input = "abcdef";
    String regrex = "abc";
    
    // 完全限定名で指定
    java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(regrex);
    java.util.regex.Matcher matcher = pattern.matcher(input);
    
    if(matcher.find()) {
      System.out.println("マッチ!");
    }
    else {
      System.out.println("マッチせず");
    }
  }
}

本当は、というか、基本は、というか、こういう完全限定名での書き方が普通なんだーっていうテイで考えて、「でもこれめんどくさいっしょ?省略記法用意したは」ってのが import 文、と思えばいいね。