Javaプログラム実行の基本
Javaプログラムを実行するには、大まかに次の手順を踏む必要があります。
- ソースファイル(
.java
)の作成 = コーディング - クラスファイル(
.class
)の作成 = コンパイル - クラスファイル(
.class
)の起動 = Javaプログラムの実行
Javaプログラム実行の手順
開発環境と実行環境の準備
Javaプログラムの実行にあたり、まずはjava
コマンド及びjavac
コマンドを実行できるようにしておく必要があります。コマンドプロンプトを開き、javac --version
java --version
でバージョン情報が出力されることを確認してください。
以降の手順では、プログラムの実行に必要なjava
コマンドと、開発ツールの一つであるコンパイラ(=javac
コマンド)の両方が必要となります。java
コマンドは実行できるものの、javac
コマンドは実行できないという場合、JREを使用している可能性があるため、JDKをダウンロードして使用するようにしてください。
ソースファイルの作成
まずはソースファイル( .java
)の作成、すなわちコーディングを行います。この例では「Hello World」を出力する以下の Main.java
を使用していきます。
public class Main {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
このファイルを任意のディレクトリに配置して、次の手順へ進みます。
クラスファイルの作成
次にクラスファイル( .class
)の作成、すなわちコンパイルを行います。これにはコンパイラ(=javac
コマンド)を使用します。
まずjavac
コマンド実行のため、Main.java
を配置したディレクトリでコマンドプロンプトを開きます。( 【Tips】エクスプローラからコマンドプロンプトを開く方法 )

続いて、作成した Main.java
を引数に指定してjavac
コマンドを実行します。
$ javac Main.java
これがコンパイラ(=javac
コマンド)によるソースファイルのコンパイルです。特にオプションを指定していなければ、同じディレクトリにクラスファイルが作成されることを確認できます。

クラスファイルの起動
最後にクラスファイル( .class
)の起動、すなわちJavaプログラムの実行を行います。
javac
コマンドで作成したクラスファイルに対して、今度はjava
コマンドを使用しますが、この時、引数には拡張子を含めずにクラスファイル名のみを指定するようにします。( ※注意 )
$ java Main
Hello World

ここでは、以下のような .java
と .class
との対比に重点を置いて説明するため、「java
コマンドの引数にはクラスファイル名を、拡張子を含めずに、指定する。」と表現しました。
- ソースファイルを対象とするコマンド / クラスファイルを対象とするコマンド
javac
コマンドの使用 /java
コマンドの使用
しかしjava
コマンドのヘルプからも確認できる通り、正確には、指定するのはクラスファイル名ではなくクラス名であるため、この表現は完全に誤りです。以下の通り、<mainclass>
を指定するよう説明があり、<classfile>
のような記述はどこにもありません。
$ java --help
使用方法: java [options] <mainclass> [args...]
(クラスを実行する場合)
または java [options] -jar <jarfile> [args...]
(jarファイルを実行する場合)
または java [options] -m <module>[/<mainclass>] [args...]
java [options] --module <module>[/<mainclass>] [args...]
(モジュールのメイン・クラスを実行する場合)
または java [options] <sourcefile> [args]
(ソースファイル・プログラムを実行する場合)
クラス・ファイルを起動するには:
java
[options] mainclass [args …]
従って正しくは、「java
コマンドの引数には、FQCN(完全修飾クラス名)を指定する。」となります。
デフォルトでは、
java
コマンドのオプションではない最初の引数は、コールされるクラスの完全修飾名です。
Javaはクラス名と同じファイル名にする必要があるため、そこに定義されたクラス名と、拡張子を除いたクラスファイル名は結果として同じものとなります。しかし指す意味は全く異なるため、コンパイル時(javac
コマンドの引数)には「ソースファイル名」を、実行時(java
コマンドの引数)には「完全修飾クラス名」を、それぞれ指定すると正確に理解しておく必要があります。
- コンパイル時
javac
コマンドの引数には「ソースファイル名」を指定する。
- 実行時
java
コマンドの引数には「完全修飾クラス名」を指定する。- 「クラスファイル名」を指定する。
- 「クラスファイルの拡張子を除いた名称部分」を指定する。
この例ではデフォルトパッケージを使用しているため、完全修飾クラス名と、拡張子を除いたクラスファイル名との違いが分かりにくいですが、パッケージを使用してクラスの定義を行った時に、この差が明確となり、重要性を増します。
javaコマンド実行時のエラー例
ここまでの手順を踏まえ、敢えて間違った引数を指定してエラー出力を確認することで、java
コマンドによる実行の理解がより深まります。ここでは次の3パターンを試してみます。
$ java Main
:クラスファイル未作成の状態でクラス名を指定$ java Main.java
:ソースファイル名を指定$ java Main.class
:クラスファイル名を指定
「$ java Main」未作成の状態でクラス名を指定
1つ目の手順であるソースファイルのコンパイルを行わずにjava
コマンドを実行してみます。引数にはクラス名(≒拡張子を除くクラスファイル名)を指定しており、構文自体は正しいものの、クラスファイルが存在しないため、指定されたクラスを参照することができず、次のようにエラーとなります。
$ java Main
エラー: メイン・クラスMainを検出およびロードできませんでした
原因: java.lang.ClassNotFoundException: Main
「$ java Main.java」ソースファイル名を指定
他の二つと異なり、このパターンはエラーとなる想定にも関わらず、正常に実行できてしまいます。
# ソースファイル名を指定(クラスファイル未作成でも実行できる)
$ java Main.java
Hello World
これは、java
コマンドの ソース・ファイル・モードを使用したソース・コード・プログラムの起動 が適用されているためです。ただしこれはあくまで、初学者によるプログラム実行や開発初期段階の試行錯誤などを想定した機能であり、大規模な開発や本番環境で動作するプログラムでは変わらず、コンパイルを行いクラスファイルを作成する必要があります。
「$ java Main.class」クラスファイル名を指定
引数にクラス名ではなく、拡張子を含むクラスファイル名を指定した場合も、同じようなエラーが出力されます。これは次のような理由からです。
本来java
コマンドの引数には完全修飾クラス名を指定しますが、これは .
区切りでパッケージ名と連結した物となります。例えば、com.example
パッケージの Main
クラスを指定する場合、実行コマンドは、$ java com.example.Main
となります。
その上で改めて、誤ってクラスファイル名を指定してしまった場合のコマンドを見てみると、$ java Main.class
となっており、従ってこれは、Main
パッケージの class
クラスと解釈しようとされることが分かります。そして当然、コンパイルされたクラスファイルに、Main
パッケージの class
クラスのような定義は存在しないため、以下のようにエラーが出力されることになります。
# コンパイル
$ javac Main.java
# クラスファイル名を指定
$ java Main.class
エラー: メイン・クラスMain.classを検出およびロードできませんでした
原因: java.lang.ClassNotFoundException: Main.class
javacコマンドのオプション
オプションを指定しない場合、javac
コマンドは対象のソースファイルと同じ場所にクラスファイルを作成します。しかし、コーディングに使用するソースファイルと、人間が読むことはなく実行時にのみ使用するクラスファイルは、それぞれを格納するディレクトリを分けて管理した方が便利です。そこで、-d
オプション を使用すると、次の例のようにクラスファイルの生成先ディレクトリを指定することができます。
1.以下のディレクトリ構成で Main.java
が配置されている。
workspace
└ src
└ com
└ example
└ Main.java
2.-d
オプションを使用してコンパイルを行う。
# カレントディレクトリは src
$ cd
C:\Users\xxx\workspace\src
# src と同じ階層の bin ディレクトリを -d オプションに指定してコンパイル
$ javac -d ..\bin com\example\Main.java
3.指定したディレクトリ以下も同じ構成でクラスファイルが生成される。
workspace
├ bin
│ └ com
│ └ example
│ └ Main.class
└ src
└ com
└ example
└ Main.java
これは次に示すように、Eclipseでコンパイルを行った時に、bin
ディレクトリにクラスファイルが作成されるのと同様の振る舞いです。
Eclipseの場合
基本的なJava実行の3ステップをコマンドで説明してきましたが、実際に開発を行う場合はEclipse等のIDEを使用することも少なくありません。
例えばjavap
コマンドを使って クラスファイルのバージョン を確認したい時、Eclipseによって作成されたクラスファイルがどこに格納されているのかが分からなければ、確認のしようがありません。
このように、IDEによってこれらコンパイル等の操作が自動的に行われている場合、各操作がどのように対応しているかを理解しておくと、柔軟なトラブルシューティングが可能となります。