質問: a * 2; return a; } } ``` ### 試したこと ・異なるパッケージ名に変更してimport →パッケージが存在しませんというエラーメッセージ ・FQCN表記を使用せずに指定 →エラーメッセージに変化なし ・-cp コマンドでクラスパスの指定 →ソースファイルがありません。というエラーメッセージ ・IDEを用いてRun →エラーメッセージに変化なし ### 補足情報(FW/ツールのバージョンなど) ・このコード自体に意味はありません。他のコードを作成時に同じようにパッケージのエラーが出たため、確認のためにコードを作成いたしました。 ・同じファイルでclassを分けた場合は問題なく作動しており、他のpackageを使用しないコードも問題なくコンパイラができるため、packageについて思い違いをしているか、そもそも文法が間違っている可能性もあります。他に似たような方の質問などを参考にしてみましたが、解決いたしませんでしたので、どなたか助力いただければ幸いでございます。
回答: javacはデフォルトで「現在のディレクトリーがデフォルトパッケージの場所」と仮定してコンパイルします。よってpakeというパッケージのソースファイル群はjavacを起動するディレクトリーに対して ./pake/Pake.java ./pake/Pake2.java という場所においてコンパイルするのが普通と思います。しかし質問者さんはこれらのソースファイルをカレントディレクトリーに置いたままコンパイルを試みたのだろうと想像します。 実はカレントディレクトリーにPake.javaをを置いてコンパイルしてもその中にJDKに含まれていないパッケージの他のクラスの参照が一切なければコンパイルに成功するのですが、他のクラスを参照した途端、参照先のクラスを見つけられずコンパイルエラーが発生します。クラスのソースファイルまたはクラスファイルはカレントディレクトリーに対してパッケージをも含んだ階層、つまり ./pake/Pake2.java のような場所にあるとjavacが仮定するからです。 もし上記のような状況でコンパイルしているのなら次のようにすると正常にコンパイル&実行ができると思います。 ``` $ ls *.java Pake.java Pake2.java $ mkdir pake $ mv *.java pake/. $ ls -R . .: pake/ ./pake: Pake.java Pake2.java $ javac pake/Pake.java $ java pake.Pake 10 $ ``` javaのパッケージ検索ルールではクラスパスに指定した各ディレクトリーは**デフォルトパッケージの場所**と解釈されます。クラスファイルが存在するディレクトリーではありません。 -cp dir としたとき、pack1.pack2.C1は dir/pack1/pack2/C1.class になければなりません。 dir/C1.class があってもそれは目的のクラスであるとはみなされません。デフォルトパッケージのC1であるとみなされます。 もっと単純な例を挙げます。 ``` $ cat Hello.java package hello; public class Hello { public static void main(String[] args) { System.out.println("hello"); } } $ javac Hello.java $ ls Hello.class Hello.java $ java Hello エラー: メイン・クラスHelloを検出およびロードできませんでした ..... (A) 原因: java.lang.NoClassDefFoundError: hello/Hello (wrong name: Hello) $ java hello.Hello エラー: メイン・クラスhello.Helloを検出およびロードできませんでした ..... (B) 原因: java.lang.ClassNotFoundException: hello.Hello ``` (A)ではjavaはカレントディレクトリーがデフォルトパッケージだと仮定してHello.classを探しに行きます。それは見つかるのですが、実際のクラスはhello.Helloですので指定された名前のものとは違っています。それゆえ「クラスがない」というエラーになります。 (B)ではhello.Helloをカレントディレクトリーに対して./hello/Hello.classにあるとみなし探しに行きますがそこにはないのでやはり「クラスがない」というエラーになります。 こういう問題は「クラスパス」あるは「ソースパス」がデフォルトパッケージの場所であるという点を理解できれば解決できると思います。