【Java】コンパイルエラーと実行時エラーの違い、例を考えた

Java

はじめに

以前、Java Bronzeの学習会中に「コンパイルエラーと実行時エラーの見分けがつきません」という質問を何度かいただきまして、勉強会中は参考書をベースに回答を続けていました。

ただ、未経験者からJava勉強始めました!という方には、特に実行時エラーのイメージが付きにくい部分もあったようだったので、コンパイルエラーと実行時エラーの違いと、実行時エラーのくだらない事例を書いてみようと思い、記事にしています。

対象

この記事が想定している読者層は次の通りです。

  • Java 初心者
  • Bronzeの勉強を始めている程度

エラーの種類

コンパイルエラー

コードに文法上のエラーがある場合、コンパイルエラーとなります。

  • 開きカッコと閉じカッコの数があってない
  • セミコロンを忘れる
  • 単純なtypo(入力誤り)

などなどが、よくある事例ではないでしょうか。

Oracle公式のJava文法仕様はこちらになります。この記事を読んでいる、特に対象者にとっては、最初はチンプンカンプンな文章だと思います。ただ、将来的には、公式ドキュメントもちゃんと読んでもらいたいと思います。

実行時エラー

文法に誤りはないが、プログラム実行時にエラーになるものです。

  • 0除算をしてしまった
  • 数値ではない文字列を、数値変換しようとした
  • nullのオブジェクトを操作しようとした

などなど、実際に動かしてみるとプログラムが動作しないものになります。(これらの場合、Javaでは「例外(Exception)」が発生するのですが、この記事では触れません。)

それぞれのエラーの対処法

コンパイルエラーは、コンパイル時点でエラー箇所を出力してくれるのでメッセージに従って修正をしていくことになります。

一方、実行時エラーは、文法自体は正しいため実行してみないと分かりません。とはいえ、実行時エラーの場合も「例外」といった形で情報を得ることができますので、「例外」の理由を確認して修正していくことになります。

実行時エラーの事例について書いてみます。プログラムっぽくは書かないです。「文法は合っているけど、これはマズいよね?」という事例にしてます。

実行時エラーの事例

実行時エラー事例

例えば、次のように5軒並んだ家があります。

家の並び。プログラムにするときは配列で表現するので0始まりです。

家が留守か問い合わせるプログラムを書こうと思います。
次のコードがサンプルコードとなります。文法上は問題ないプログラムですが、マーカーの箇所で実行時エラーになります。

public class Sample {
  public static void main(String[] args) {
    // 平屋建ての集合住宅
    House[] houses = new House[5];
    if (houses[5].isAbsence()) {  // 実行時エラーになる場所
      System.out.println("留守だったので帰りました。");
      return;
    }
    // 留守じゃない時の処理を続ける(省略)
  }
}
class House {
  /* 留守の状態 */
  private boolean absence = false;
  public boolean isAbsence() {
    return absence;
  }
}  

isAbsence()メソッドで、家の留守状態を確認します。が、マーカーの箇所で指定している番地に、家は存在しません。そのため、プログラムは何を実行すればいいかわからない⇒実行できない⇒実行時エラーとなります。

houses[5].isAbsence()を命令された時のプログラムのお気持ち

その他のエラー

その他のエラー事例

実行時エラーに近いですが、コンパイルエラーにもならず、例外も出さないエラーケースについてです。要は「動作しているけど、結果が間違っている」ケースですね。

たぶん豚が好きな女性
You like a pig.

画像を見て、「あなたは豚が好きです」と表現するのは正しいでしょうし、言われた側も素直に受け取ることができます。

ただ、次のように、表現の仕方を間違えるとどうなるでしょうか。

You are like a pig.

こちらも、文法に誤りはないです。が、実行すると間違いなく人間関係にエラーをもたらします。なぜなら、文法は合っていても、英文の意味が「あなたは豚のようだ」なのですから。不快にならない人はほとんどいないのではないでしょうか。

多くの人がこうなるはず・・・

最後に

ある程度経験を積んだエンジニアであっても、コンパイルエラー・実行時エラーに見舞われることはザラです。エラーにぶつかって、解決していくほど理解が深まりますので、どんどんコンパイルして、動かして、を繰り返すことが肝要ではないかなぁと思います。

参考文献

The Java® Language Specification (Java SE 11 Edition)

The Java® Language Specification

Javaにおける字句解析の仕様、3.Lexical Structure ~ 10.Arraysを参照。

コメント

タイトルとURLをコピーしました