Because We Love Happy Coding

フリーライターからエンジニア × 講師。発信力だけあり余ってる感じ

Javaのパッケージをimoprtする際、ワイルドカードを使うかどうかで挙動が異なる謎

今日もまたコーディング。だって僕らはHappy Codingが大好きだから。

講師の仕事でパッケージを作ったら何かの罠を踏み抜いたらしいので、とりあえず現象だけ。

環境

Java8 1.8.9_162 Windows7

ディレクトリ構成

  • src/
    • senario.java // import hoge.fuga.*
    • senario.class
    • Foo.java // package hoge.fuga
    • Bar.java // package hoge.fuga
    • hoge/
      • fuga/
        • Foo.class
        • Bar.class

hoge.fugaパッケージを作ろうと上記のようなソースコードを構成した。

Senario.javaコンパイルすると発生する現象

Senario内のimport文が import hoge.fuga.*;の場合

以下のエラーが発生する

コンパイルエラー Fooにアクセスできません
ソースファイル .¥Foo.javaは不正です。
ファイルにクラスFooが含まれていません。
削除するか、ソースパスの正しいサブディレクトリにあるかを確認してください。

この場合、Foo.javaおよびBar.javaを削除すると問題なくコンパイル完了する。

Senario内のimport文が import hoge.fuga.Foo; import hoge.fuga.Bar; の場合

問題なくコンパイルが行われる。

どういうこと?

どうもimport文にワイルドカードを使った時のみ、同じディレクトリ内のjavaソースをチェックしているっぽい。

classpathの問題?

実務上、パッケージをimportする際にソースコードが共存していることはあまりないはずなので、発生することは少ないと思うが……。

なんでこんなふうにワイルドカードを使うかどうかでコンパイルの挙動が異なるのか、ご存じの方がいたらコメントかTwitter(@mogami74_en)で教えてください。