コンパイルを理解する

コンパイルは、ソースを検査して実行用のクラスファイルへ変換する段階です。構文・型・名前の誤りがどこで検出されるかを理解し、javacの入力・出力・版指定を使い分けます。

この単元で学ぶこと

  • コンパイル時の構文と型の違反を判断する
  • javacのソース指定と出力先指定を区別する
  • 言語版とAPIの互換条件を判断する

本文解説

入力ファイルを指定する javac Main.javaは現在のディレクトリのソースを読みます。通常のこの形式で指定するのはMainというクラス名だけでなく.javaを含むファイル名です。コンパイラがソースを読み、構文や型を検査してclassを生成します。

変換時に検査すること int n=true;や宣言していないxの参照は、ソースの型や名前の規則に合わず拒否されます。エラーメッセージの行は問題の手掛かりですが、閉じ括弧の欠落では原因より後の位置を指すこともあります。対応する宣言と区切りも見ます。

戻り値と型 int value(){return "A";}は返す値の型が一致しません。voidメソッドの結果をintへ代入することもできません。コンパイラは、メソッド名が存在するだけでなく引数と戻り値の型まで検査します。

出力先-d javac -d out Main.javaはclassをout配下へ置きます。package app;ならout/app/Main.classという階層になります。次の起動でjava -cp out app.Mainのようにその出力先を検索経路へ指定します。-dの指定だけで実行時のクラスパスが恒久的に設定されるわけではありません。

ソースの文字コード 日本語のコメントや文字列をUTF-8で保存したならjavac -encoding UTF-8 Main.javaのように読み方を明示できます。文字コード指定はソース文字の解釈であり、intの幅やプログラムの型を変更する指定ではありません。

言語版と公開API javac --release 11はJava 11に対応する言語規則・クラス対象・公開APIを使うための指定です。Java 11にない構文を使うと、ツール本体が新しくても拒否されます。この指定でテストを実行したJVMそのものまでJava 11へ交換されるわけではありません。

成功と実行時失敗 int[] a={2};a[5]というアクセスは、型検査を通っても実行時に範囲外です。コンパイル成功は全入力で正常に動く保証ではありません。逆に、ソースの型違反は入力データを変えてもコンパイル時に拒否されます。

古いclassの残存 以前に成功して作られたMain.classがあっても、後のソースが誤っていてコンパイルが失敗すれば、新しい内容が反映されたとは言えません。古いclassが残る環境でjava Mainだけを実行すると、前の結果を見る可能性があります。ビルドの終了結果と出力先を確認してから実行します。

図解

javacで確かめること
コンパイル成功後に、別途起動して実行結果を確認する。

重要ポイント

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

間違えやすい点

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

用語解説

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

関連教材

参考資料

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

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