Java 入門

Java のコンパイルと実行

Javaコードのコンパイルと実行は、Java開発において最も基礎的でありながら、最も核心となるステップです。プログラムを実行し、コードの動作結果を確認するためには、これらの手順を正しく理解することが不可欠です。本章では、Javaのソースコードをバイトコードにコンパイルする方法と、そのバイトコードをJava仮想マシン(JVM)で実行するプロセスについて、ステップ・バイ・ステップで解説します。

1. コンパイルプロセス

コンパイルとは、人間が理解できるソースコード(この場合はJavaコード)を、マシンが実行可能なコードに翻訳するプロセスです。しかし、Javaは現在のオペレーティングシステム(OS)向けの低レベルなマシン語に直接コンパイルされるわけではありません。その代わりに、「バイトコード(bytecode)」と呼ばれる中間形式にコンパイルされます。このバイトコードはプラットフォームに依存しないため、Java仮想マシン(JVM)がインストールされているあらゆるシステム上で実行することが可能です。

1.1 ソースコードからバイトコードへ

Javaコンパイラである javac が、この翻訳作業を担当します。コンパイル中に発生する具体的なステップは以下の通りです:

  • 構文およびセマンティクス分析: コンパイラはまず、コードに構文エラー(例:セミコロンの欠落、キーワードのスペルミス)やセマンティクスエラー(例:型の不一致、未宣言の変数の使用)がないかチェックします。エラーが見つかった場合、コンパイルプロセスは停止し、開発者はそれらを修正する必要があります。
  • コード生成: コードにエラーがなければ、コンパイラはバイトコードを生成します。バイトコードは、JVMが理解・実行できる一連の命令(インストラクション)で構成されています。
  • Classファイルの作成: 生成されたバイトコードは、.class ファイルに保存されます。この .class ファイルの名前は、Javaソースコード内で定義されたクラス名と完全に一致します(例:HelloWorld.java をコンパイルすると HelloWorld.class が生成されます)。

コード例:

例えば、HelloWorld.java という名前のシンプルなJavaプログラムがあるとします。

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

このコードをコンパイルするには、ターミナルまたはコマンドプロンプトで以下のコマンドを入力します:

javac HelloWorld.java

コンパイルが成功すると、HelloWorld.java ファイルと同じディレクトリに HelloWorld.class ファイルが生成されます。

1.2 コンパイルエラーの処理

コンパイルエラーは日常的な開発において非常に一般的なものです。Javaコンパイラは非常に詳細なエラーメッセージを提供し、コード内の問題を迅速に特定・修正するのを助けてくれます。

例:

HelloWorld.java 内で誤って System.out.printlnSystem.out.prntln と綴ってしまったとしましょう:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.prntln("Hello, World!"); // 意図的なスペルミス
    }
}

このコードをコンパイルしようとすると、次のようなエラーが表示されます:

HelloWorld.java:3: error: cannot find symbol
        System.out.prntln("Hello, World!");
                  ^
  symbol:   method prntln(String)
  location: variable out of class System
1 error

このエラーメッセージは、以下の重要なヒントを明確に示しています:

  1. エラーが発生したファイル名 (HelloWorld.java)
  2. エラーが発生した具体的な行番号 (3)
  3. エラーの内容説明 (cannot find symbol:シンボルが見つかりません)
  4. 見つからない具体的なシンボル (method prntln(String)prntln というメソッドが見つかりません)
  5. コンパイラがそのシンボルを探した場所 (variable out of class System)

エラーメッセージを注意深く読むことで、スペルミスを迅速に発見し、修正することができます。

2. 実行プロセス

Javaコードをバイトコードにコンパイルできたら、次は実行です。ここで Java仮想マシン (JVM) の出番となります。

2.1 JVM の核心的な役割

JVMは、Javaバイトコードを実行するための専用のソフトウェア環境です。コンパイル済みのコードと基盤となるOSの間の「仲介役」として機能します。このメカニズムこそが、Javaにクロスプラットフォーム能力を与えています。つまり、同じバイトコードが、互換性のあるJVMを備えたあらゆるシステムで動作するのです。

実行中には以下のステップが行われます:

  • ロード (Loading): JVMが .class ファイルをシステムメモリに読み込みます。
  • バイトコード検証 (Bytecode Verification): JVMがバイトコードを厳格にチェックし、それが正当であり、システムのセキュリティ制限に違反していないことを確認します。
  • インタープリタ実行 / 即時コンパイル (JIT Compilation): JVMはバイトコードを逐次解釈(インタープリタ)して実行するか、あるいは JIT (Just-In-Time) コンパイラ を使用してバイトコードをOSのネイティブなマシン語にリアルタイムで翻訳し、実行速度を劇的に向上させます。現代のJVMは主にJITコンパイル技術に依存しています。
  • 実行 (Execution): JVMがバイトコード(またはJITコンパイルされたネイティブコード)を実行し、プログラムで指定されたすべての操作を正確に完了させます。

2.2 Javaプログラムの実行

コンパイル済みのJavaプログラムを実行するには、java コマンドを使用し、その後に main メソッドを含むクラス名を指定します(.class 拡張子は絶対に付けないでください)。

例:

先ほど作成した HelloWorld.class ファイルを実行するには、以下のコマンドを使用します:

java HelloWorld

これにより HelloWorld クラス内の main メソッドが実行され、コンソールに "Hello, World!" と出力されるはずです。

2.3 main メソッドの深い理解

main メソッドはJavaプログラムのエントリポイントです。プログラムを実行すると、JVMは自動的に以下の特定のシグネチャを持つ main メソッドを探します:

public static void main(String[] args) {
    // ここにコードを記述します
}
  • public: main メソッドは public(公開)として宣言されている必要があります。これにより、JVMが外部からアクセスして起動できるようになります。
  • static: static(静的)である必要があります。これにより、JVMはそのクラスのインスタンス(オブジェクト)を作成することなく、メソッドを直接呼び出すことができます。
  • void: main メソッドの実行完了後に何も値を返さないことを示します。
  • String[] args: main メソッドは文字列の配列をパラメータとして受け取ります。これらはプログラム実行時にコマンドラインから渡すことができる外部命令(コマンドライン引数)です。これについては、後のモジュールで詳しく解説します。

3. ランタイムエラーの処理

ランタイムエラーは通常 例外 (Exceptions) と呼ばれ、プログラムの実行中に発生するエラーです。無効なデータの入力、ゼロによる除算、存在しない配列要素へのアクセスなど、原因は多岐にわたります。例外処理のメカニズムについては、後の専用モジュールで深く掘り下げます。

サンプルコード:

public class Division {
    public static void main(String[] args) {
        int numerator = 10;
        int denominator = 0;
        int result = numerator / denominator; // 潜在的なゼロ除算エラー
        System.out.println("結果: " + result);
    }
}

このコードを実行すると、数学的にゼロで割ることはできないため、プログラムは即座に ArithmeticException(算術例外)をスローします。この時点でプログラムは異常終了し、コンソールにエラーのスタックトレースが出力されます。

4. 統合開発環境 (IDE) の利用

コマンドラインだけでもJavaコードのコンパイルと実行は可能ですが、統合開発環境 (IDE) を使用すると、より便利で機能豊富な開発体験が得られます。IntelliJ IDEA、Eclipse、NetBeansといったIDEは、コンパイルと実行のプロセスを完全に自動化し、コードの自動補完や強力なデバッグツールを提供します。

4.1 IDE でのコンパイルと実行

IDEによって操作は異なりますが、基本的なフローは共通しています:

  • プロジェクトの作成: IDE内で新しいJavaプロジェクトを作成します。
  • コードの記述: インテリジェントなエディタでJavaコードを入力します。
  • コンパイル: ほとんどのIDEは、コードの入力時やファイルの保存時に自動的にコンパイルを行います。メニューやショートカットキーから手動でビルド(コンパイル)することも可能です。
  • 実行: 通常、緑色の「実行 (Run)」ボタンをクリックするか、ショートカットキーを押すだけです。IDEがバックグラウンドで(必要に応じて)コンパイルを行い、即座に実行します。
  • 出力の確認: プログラムの実行結果は、IDE下部のコンソール (Console) ウィンドウに直接表示されます。