例外処理とはプログラムがなんらかのエラーを出したときに、処理を中断して別の処理を行うことだ。
予想外のエラーが出ないプログラムなんてほぼない。プログラミングをする上で、なくてはならないものになっている。
このページでは例外処理について初心者向けにご紹介しよう。
例外処理とは?
コンパイルを行っているのにエラーが起きる?
多くのプログラミング言語には例外処理という機能がある。例外処理とはその名の通り、通常でないことが起きた場合に行う処理のことだ。
Javaなどのコンパイル言語ではプログラミングしたソースコードを実行させる前にコンパイルを行い、コンピュータが理解できる形式に変換する。
ソースコードに文法の間違いなどがある場合はコンパイルの時点でエラーが出力され、実行できないため、基本的なミスや間違いはJavaを実行する前に大体は消すことができる。
しかし、プログラムの中には、コンパイル時にはエラーがなく実行できるが、実行している途中に起きるエラーというものがある。
例えば、あるファイルを開こうとしたが、そのファイルが存在しなかったなどの場合だ。コンパイル時点ではファイルがあるかどうかはチェックされないが、実際にプログラムを実行してみたらあるはずのファイルが無かったというようなことはある。
コンパイルの時点ではわからなかったが、実行してみて気づくエラーだ。
プログラムはそのファイルを開こうとしたが無かったため処理が止まってしまう。
しかし、このJavaコードに「例外処理」を記述しておけば、処理を止めることプログラムをそのまま動かすこともできる。また、例えばファイルがないというメッセージを表示することも可能だ。
一般的なプログラムでの例外の対処方法
処理としては次のような形だ。
例外処理を行うためには、まず起きた例外を検知する必要がある。
例外処理がサポートされているプログラミング言語では、自動で起きた例外を検知して、その例外を処理できる箇所に投げる。
投げられた例外を捉えることをcatchするといい、catchした例外に対して、プログラマが処理を記述することができる。
多くのプログラミング言語では、tryというブロックに処理を記述し、その中で起きた処理についてcatchブロックを作成し、投げられた例外について処理を記述する。
Javaの例外処理の特徴
多くのプログラミング言語に備えられている例外処理の機能であるが、Javaならではの特徴ももちろんある。
Javaの例外処理の特徴を理解することも重要だ。
先にtry-catchの基本を理解したければ下の記事を先に読んでもらったほうがいい。
ここでは、さらっと読んでおいていただき、知っておくくらいで十分だ。
例外もオブジェクト
Javaはオブジェクト指向言語だ。オブジェクト指向はすべてをモノとして扱うので、例外もオブジェクトとして扱う。
Javaの例外処理には「Throwable」というクラスのサブクラスである「Exception」クラスがあり、そこからさらに派生した「RuntimeException」クラスがある。
例えばファイルが存在しない場合の例外処理である「FileNotFoundException」クラスは「Exception」クラスのサブクラスであるように、Javaで使用する例外処理のクラスはすべて「Exception」クラスか「RuntimeException」クラスを継承したサブクラスだ。そのため、「Exception」クラスか「RuntimeException」クラスを継承したサブクラスを作ることで独自の例外処理クラスを作成することができる。
検査例外
「Exception」クラスと「RuntimeException」クラスには大きな違いがある。
「Exception」クラスが使用される可能性がある場合は、プログラムの中で例外処理を書かなくてはならない。
ファイルを読み込む処理をプログラムで書く場合、「Exception」クラスのサブクラスである「FileNotFoundException」クラスが呼ばれる可能性があるため、例外処理を記述しないソースコードはコンパイルエラーになり、実行することができない。
ソースコード内の例外処理の記述漏れをコンパイル時点でエラーにすることを「検査例外」といい、Javaの例外処理の大きな特徴である。
「RuntimeException」クラスのサブクラスには、nullの値のオブジェクトを参照した場合の例外処理である「NullPointerException」クラスや、配列の範囲外を指定した場合の例外処理である「ArrayIndexOutObBoundsException」クラスなどがあり、これらの例外処理は起こる可能性があったとしても、コンパイルエラーになることはない。これを「非検査例外」という。
「検査例外」はあるはずのファイルが存在しない場合など、プログラマにとっては防ぎようがないエラーを想定している。
一方で「非検査例外」はプログラマの人為的なミスで起こり得るエラーを想定している。
Javaの検査例外という機能は例外処理の記述を強制されるため、記述するソースコードが多くなり見やすさが損なわれたり等々デメリットもある。
ただ、コンパイル時点で起こり得るエラーを把握できるため、堅牢なシステムを構築するためは便利だ。
まとめ
このページでは例外処理とは?についてまとめてきた。
実際のコーディングについては、次のページを参考にしてほしい。