例外とは、簡単に言うとコンパイルは成功するのに、そのプログラムの実行時に発生する予期せぬエラーにより生成されるオブジェクトのことです。例外処理は実際の Javaプログラムでは必ず行うようにしましょう。優秀なプログラマやSEほど発生する例外を想定しそれに対応する堅固プログラムになっています。
具体的に実行時に発生する例外は以下のようなものがありますが、Javaではこのような例外処理のための機構を用意しています。エラーを通知するので、それに対する処理を実行することが可能になります。
- 0による除算
- 範囲外の配列要素へのアクセス
- ファイルのオープンができない
- データベースへ接続できない
- プログラミングでは回避できない何らかのエラー
実際に例外が発生するプログラムを見てみましょう。
[ Example_12_01.java ]
public class Example_12_01{
public static void main(String args[]){
int a[]=new int[10];
for(int i=0;i<11;i++){
a[i]=100;
System.out.println(Integer.toString(a[i]));
}
}
}
[ 実行結果 ]
100
100
100
100
100
100
100
100
100
100
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at ExceptionTest.main(ExceptionTest.java, Compiled Code)
上記のプログラムは問題なくコンパイルすることが出来ます。しかし実行してみると 0 〜 9までの要素しか存在しない配列の 10番目の要素にアクセスした時に要素外の配列にアクセスしたことを示す例外の
ArrayIndexOutOfBoundsException (以下参照)が発生してプログラムが停止してしまっています。
java.lang.Object
|
+--java.lang.Throwable
|
+--java.lang.Exception
|
+--java.lang.RuntimeException
|
+--java.lang.IndexOutOfBoundsException
|
+--java.lang.ArrayIndexOutOfBoundsException
Javaではエラーの処理や管理機能として例外処理がサポートされていて、この機能を用いて、実行中の予期せぬエラーに備えます。 Javaの例外処理は
try , catch , finally, throw, throws のキーワードから構成され、例外が発生する可能性がある場合は明示的に例外を監視します。
今回はそのうち try , catch , finallyについてみてみます。
[ 構文 ]
try {
// 例外の発生が予測されるコード
} catch(例外の型名 変数名) {
// 例外が発生したときの処理
} finally {
// 例外をCatchしてもしなくても実行される処理
}
try
tryステートメントは例外の発生が予測される処理ブロックを { } で囲みます。 実際に例外が監視されるのは try { } で囲まれた処理ブロックになります。
catch
tryステートメントに次にいくつかの catchステートメントを続けて記述します。catchステートメントは複数記述することが可能で、引数に例外オブジェクトを指定します。実際に例外が発生した時、JVMは catchステートメントの上から順に検索を行い、catchステートメントのパラメータと発生した例外オブジェクトが一致した時に catchブロックを実行します。
発生した例外の親クラスを引数に取る catchステートメントでも処理することが可能です。オブジェクトツリーでいうと、ArrayIndexOutOfBoundsExceptionは Throwableや Exceptionクラスでも捕捉することが可能です。
ただし先頭の catchステートメントが引数で Throwableを受け取り、次の catchステートメントで ArrayIndexOutOfBoundsExceptionを受け取るといった記述は出来ません。到達不能コードとしてコンパイルエラーになります。
finally
catchブロックが終了した時点でこのfinallyブロックが実行されます。tryブロックや、catchブロックに
return ステートメントが記述されていても、この finallyブロックは必ず実行されます。 一般的に finallyブロックでは、データベースからの切断処理等を記述します。finallyブロックは省略可能です。
では先ほど例外が発生したコードを try、catch、finallyを記述してそれぞれの役割を見てみましょう。
[ Example_12_01.java ]
public class Example_12_01{
public static void main(String args[]){
int a[]=new int[10];
try{
for(int i=0;i<11;i++){
a[i]=100;
System.out.println(Integer.toString(a[i]));
}
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("ArrayIndexOutOfBoundsExceptionが発生しました。");
return;
}finally{
System.out.println("finallyブロックを実行します。");
}
}
}
[ 実行結果 ]
100
100
100
100
100
100
100
100
100
100
ArrayIndexOutOfBoundsExceptionが発生しました。
finallyブロックを実行します。
このように例外が発生してもプログラムの実行は停止せず、catchブロックが実行されて、さらに catchブロック内に return ステートメントがあるにも関わらず finallyブロックが実行されていることが分かると思います。
もしも例外が発生したとき、プログラムを止めずに、そのまま実行させることができます。Javaでは、基本的に、例外が発生する可能性がある箇所では、必ず例外処理を記述しなければいけません!覚えておきましょう。 また SJC-Pでは finallyブロックに関する出題もありますので、きちんと理解しておきましょう。