ソースコード・コンパイル・実行の違いと使い分け

ソース編集、コンパイル、クラス起動は別の作業です。生成物とコマンドとエラーが出る段階を対応付け、変更が反映されない理由や、起動に必要なファイルを具体的な事例から判断します。

この単元で学ぶこと

  • ソース・class・実行結果を対応付ける
  • 失敗した段階と修正対象を判断する
  • 二段階起動とソース直接起動を区別する

本文解説

三つの段階を対応させる Main.javaのmainをSystem.out.print("old");とし、javac Main.javaでclassを生成すると、java Mainでoldが表示されます。ソースは記述、classは変換後の形式、oldは実行した結果です。三つを同じファイルや同じ操作として扱わないことが基本です。

保存だけでは生成物は変わらない そのソースをnewと表示するよう保存しても、javacをやり直す前にjava Mainを起動すれば、既存classのoldが表示されます。これは編集が失われた証拠ではありません。どのclassを生成し、どこから起動したかを確かめる必要があります。

コンパイル失敗後の実行 以前の有効なMain.classが残っている場所で、新しいソースの構文エラーを直さずjava Mainだけを実行すると、古いコードが動くことがあります。コンパイルの終了状態を見ずに、出力が出たから最新ソースも正しいと判断しないでください。

出力先と検索先の食い違い 新しいclassをoutへ生成しても、起動時に-cp oldを指定すればold側にあるclassを読みます。ソースの置き場所、-dによる出力先、-cpによる実行時検索先を別々の項目として確認します。環境変数へ頼らず例では-cpを明示します。

コンパイルで見つかる違反 boolean b=1;のような型違反や、メソッド呼出しの括弧不足はソースを修正します。mainへ渡す引数の値を変えるだけでは解決しません。コンパイラが読み取るプログラムそのものが有効でないためです。

起動時と本体実行時の失敗 クラスパスにMainが見つからない場合は起動するクラスを準備・指定する問題です。正しいmainへ入った後のparseInt("x")は入力形式の問題でNumberFormatExceptionです。どちらも画面にエラーが見えても、同じ修正を行うわけではありません。

ソース直接起動は別形式 Java 11では単一ソースファイルをjava Main.javaという形式で起動する機能もあります。この形式はソースを読み、その場でコンパイルして実行します。java Mainという通常のクラス起動が、常に隣のMain.javaを再コンパイルするという意味ではありません。最初はjavac→javaの二段階を基準に区別します。

配布と再現の条件 classからの通常起動では、mainを含むclassだけでなく実行で必要になる補助classやライブラリも検索可能にします。ソースは変更や再ビルドに必要ですが、すべての通常起動で元の.javaが必須とは限りません。対応JVMと依存関係と起動指定を揃えて結果を確認します。

図解

編集と変換と起動の違い
編集したファイルと起動したclassが同じ版かを確かめる。

重要ポイント

  • javacの入力はソースファイル名。
  • -dはclassの出力先を指定する。
  • -encodingはソースの文字コードの指定。
  • --releaseは対応する言語・class対象・公開APIを制約する。

間違えやすい点

  • classが作られたことを期待する実行結果の保証と考えない。
  • 失敗後に残った古いclassを新しい生成物と誤認しない。
  • 警告とコンパイルエラーを同じものと考えない。

用語解説

コンパイルエラー
ソースを有効なプログラムとして変換できない検査上の誤り。
出力先
生成されたclassファイルを置くディレクトリ。
対象版
生成物や使用できる言語・APIを対応させるJavaの版。

関連教材

参考資料

教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。

確認問題の出題・採点や学習履歴の保存にはログインが必要です。