Javaソースプログラムのコンパイルは誰でも知っています。つまりcmdソースファイルがあるディレクトリに移動してjavac **.javaそれだけで済みます。プログラムにパッケージ宣言がある場合、単純に直接javac **.javaできるでしょうか?答えはもちろんno、次に簡単な例で、直接javac **.javaどうなるかを示します。

次のとおりです:F:\javaweb2班\20160531ディレクトリにA.javaファイルがあります。ソースファイルにパッケージ宣言があることに注意してください:

実例

package mypack; public class A { String name; int age; public void setName(String _name){ this.name =_name; } public void setAge(int _age){ this.age = _age; } public String getName(){ return this.name; } public int getAge(){ return this.age; } public static void main(String[] args){ A a = new A(); //a.setName("zs"); a.name="zs"; a.setAge(18); System.out.println(a.getName()+a.getAge()); } }

ここでA.javaを直接コンパイルします。javac A.java の結果は次のとおりです:

現在のディレクトリにA.classバイトコードファイルが現れたのがはっきりわかります。このまま直接実行できるでしょうか?試してみましょう!

このようなエラーが発生しました。原因はA.javaにパッケージ宣言があるためです。A.javaソースファイルを実行するとき、Java仮想マシンはまずA.javaの現在のディレクトリでバイトコードファイルを探します。今回は見つかりましたが、A.javaにパッケージ宣言があるため、Java仮想マシンは続いてパッケージディレクトリにA.classバイトコードファイルがあるかどうかを探します。そこで見つかって初めて実行に成功します。信じられないなら実験してみましょう!(ここで、パッケージ宣言付きのA.javaのコンパイル方法、つまりパッケージ化コンパイル javac -d . A.java も教えます)

これでパッケージ化コンパイルに成功しました。このときmypackディレクトリにA.classファイルが現れたのがわかります。次に実行してみましょう

このとき、実行してもやはり通りません??これはなぜでしょうか?ここは多くの初心者が遭遇する問題です。ここで皆さんが必ず覚えておくべきことは:Javaコマンドの引数は「クラスの完全修飾クラス名」であり、「ファイル名」ではありません。

このソースプログラムの完全修飾クラス名はmypack.Aのはずです。したがって、次のように書くべきです:java mypack.A

これで実行に成功しました!

焦らないで!!この後もっと素晴らしい内容があります!パッケージの使い方として、パッケージのインポート・作成・コンパイルを説明しないわけにはいきません!

今回は別のテストクラスTest.javaを導入します。コードは次のとおりです:

実例

import mypack.A; public class Test{ public static void main(String[] args){ A a = new A(); a.setName("zs"); //a.name="zs"; a.setAge(18); System.out.println(a.getName()+a.getAge()); } }

コンパイルと実行は次のとおりです:

結果は予想どおり、間違いなくコンパイル・実行できます。実行フローは次のとおりです:Test.javaをコンパイルした後に生成されたバイトコードファイルは現在のディレクトリにあります(コンパイル時に、mypack内にA.classファイルがあるかどうかを探します。なければコンパイルは通りません)。実行時、Test.javaにはパッケージ宣言がないため、Java仮想マシンはまず現在のディレクトリでTest.classを見つけて実行します。プログラム内でAクラスを参照する箇所まで実行すると、Java仮想マシンは現在のディレクトリにA.classバイトコードファイルがあるかどうかを確認します。このとき、たとえ見つけたとしても、ソースプログラムのパッケージインポートに従ってパッケージ内にA.classを探しに行き、見つかって初めて実行に成功します(実はコンパイル段階ですでに探しています!)

さらに進んで:テストクラスTest.javaにパッケージ宣言 package mypack1; を追加するとします。

このときTest.javaをパッケージ化コンパイルします。ここでまた2つの知識ポイントを説明します:1. パッケージ化コンパイル時には、パッケージディレクトリが自動的に作成されるため、自分でパッケージ名のフォルダーを作成する必要はありません;2. 現在のディレクトリにコンパイルまたはパッケージ化コンパイルが必要な複数のJavaファイルがある場合、javac -d . *.javaコマンドを使用すると、現在のディレクトリにあるすべてのJavaファイルを、プログラム内にパッケージ宣言があるかどうかに応じてコンパイルまたはパッケージ化コンパイルできます。

このとき、Test.javaファイルをどのように実行すればよいでしょうか?java Test.java でしょうか??明らかにそれではダメです。前に説明したことを覚えていますか:Javaコマンドの引数は「クラスの完全修飾クラス名」であり、「ファイル名」ではありません。

したがって、次のように実行する必要があります:

これで:

上記で説明したのはすべて一般的なケース、つまりクラスパスが現在のディレクトリにある場合です。クラスパスが現在のディレクトリにない場合でも実行できるでしょうか?また、どのように実行すればよいでしょうか?

下図のように、Test.javaを外側の1つ上のディレクトリに置きました。この場合、自分でclasspathパラメータを設定する必要があります。例:F:\javaweb2班>java -cp F:/javaweb2班/20160531 mypack1.java;または任意のディレクトリで:java -cp F:/javaweb2班/20160531 mypack1.java

これで成功です!具体的な実行フローは各自で分析して理解してください!

まとめ

    1. Javaコマンドの引数は「クラスの完全修飾クラス名」であり、「ファイル名」ではありません。
  • 2. パッケージ化コンパイル時には、パッケージディレクトリが自動的に作成されるため、自分でパッケージ名のフォルダーを作成する必要はありません。
  • 3. 現在のディレクトリにコンパイルまたはパッケージ化コンパイルが必要な複数のJavaファイルがある場合、javac -d . *.javaコマンドを使用すると、現在のディレクトリにあるすべてのJavaファイルを、プログラム内にパッケージ宣言があるかどうかに応じてコンパイルまたはパッケージ化コンパイルできます。
  • 4. クラスパスが現在のディレクトリにない場合は、次を使用する必要がありますjava -cp ...。例:java -cp F:/javaweb2班/20160531 mypack1.java。
  • 5. Java仮想マシンがパッケージ宣言とパッケージインポートに基づいてバイトコードファイルを実行するフローを明確に理解すること。

原文アドレス:https://www.cnblogs.com/xiaoming0601/p/5551113.html