ソースコード・コンパイル・実行のコードトレース
コンパイルに成功したコードについて値の変化と出力を追い、失敗するコードでは最初に止まる段階を特定します。各断片は特記がなければ正しいpublic static void main(String[] args)の中へ置くものとし、Javaの整数と配列の基本を使います。
この単元で学ぶこと
- ソースファイル、classファイル、JVMの役割を説明できる
- javacとjavaに正しい引数を指定できる
- コンパイルエラーと実行時例外を区別できる
本文解説
トレースの準備 Main.javaにpublic class Mainと通常のmainを用意し、各例の断片をmainの中へ一つずつ入れます。例を切り替えたら必ずjavac Main.javaが成功したことを確認してからjava -cp . Mainを実行します。複数例を一度に入れると同じ変数名の重複など別のエラーが入り得ます。
例A:代入前の値を使う int a = 3; int b = a + 2; a = 8; System.out.print(b);は5を出します。bへ代入する時点でaは3です。その後aを8にしてもbがa + 2という式を記憶して再計算するわけではありません。表にするとa/bは3/未宣言、3/5、8/5の順です。
例B:整数の除算 int total = 7; int people = 2; System.out.print(total / people);は3です。整数同士の除算は小数部分を切り捨てる方向、正確には0へ近づく方向へ丸めます。total % peopleなら余り1です。3.5を必要とする場合は浮動小数点の計算として設計します。
例C:計算と表示の順番 int value = 2; System.out.print(value); value = value + 4; System.out.print(value);は改行なしで26です。出力済みの2が後から6に書き換わるわけではありません。printlnなら各出力の後に改行が加わります。文字列として並ぶ出力と整数加算を混同しません。
例D:実行中の中断 System.out.print("A"); int d = 0; System.out.print(4 / d); System.out.print("B");は最初のAの後にArithmeticExceptionで中断し、Bには到達しません。標準出力のAと、通常標準エラーへ表示される例外情報を区別して確認します。
例E:未初期化と型の不一致 int x; System.out.print(x);ではローカル変数xに値が確実に代入されていないためコンパイルできません。int x = "4";も型が違うためコンパイルできません。どちらも実行結果の数字を予測する前に検査で止まります。intのフィールドに既定値0があることをローカル変数へ一般化しないでください。
例F:引数を使う System.out.print(args.length);はjava -cp . Main east westなら2です。System.out.print(args[1]);ならwestです。引数がeastだけなら要素1はなく例外になります。要素番号は0から始まり、最大の有効番号は長さ-1です。
検証の記録 各例について「コンパイル成否」「実行直前の引数」「標準出力」「例外の有無」の四項目を記録します。コンパイルエラー例ではjavaを続けて実行せず、実行時例外例ではその前に出た文字まで確かめます。例外表示の行番号や文言は実装やコード配置で変わり得るので、例外の種類と到達した処理を判断します。
図解
重要ポイント
- javacは変換、javaは起動。
- 通常起動ではファイル名ではなくクラス名を渡す。
- 型の不一致と実行時のゼロ除算は発生段階が異なる。
- ソースを変えたら再コンパイルし、成功を確かめる。
間違えやすい点
- コンパイル成功を正常終了の保証としない。
- 古いclassファイルの実行を修正成功としない。
- mainの引数名と必要な型・修飾子を混同しない。
用語解説
- ソースコード
- Javaの規則で書いたプログラムの文章。通常.javaへ保存する。
- コンパイル
- ソースを検査し、実行環境用の形式へ変換する処理。
- バイトコード
- JVMが扱う命令形式。classファイルに格納される。
- JVM
- Javaのバイトコードを実行する仮想マシン。
- 実行時例外
- プログラムを実行している間に発生する例外。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
確認問題の出題・採点や学習履歴の保存にはログインが必要です。