プログラミング応用b 第6回『例外』 |
【エラー処理の課題】
プログラムにとって必要不可欠でありながら,扱いが難しいもののひとつが,エラー処理である。
どのようにエラーを回復するか,という点については,それぞれのエラーごとに対応が違うので,
ここではふれない。
ここでは,『例外』というJavaのエラー処理の仕組みを学ぶ前に,エラー処理を行うためのメカニ
ズム上の課題を考えてみよう。
●エラー処理記述の複雑さ
エラー処理を行う場合,もっとも原始的な方法は,エラーが起こってないかどうかをif文でチェッ
クし,エラーが起こっていない場合は通常の処理を行い,エラーが起こっていた場合は,else節でエ
ラー処理を行うという方法である。
たとえば,List 1のように,4つの処理を実行している場合を考えてみよう。この例では,処理1か
ら処理4まで,順序よく処理が記述されていて(List 1-(1)),処理の流れが明確である。
しかし,この例では,エラー処理は一切行っていない。そこで,List 1の各処理ごとに
・エラーが起こっていないかどうかの検査
・エラーが起こっていた場合のエラー処理
を追加した例が,下のList 2である。
処理1〜処理4が行われている部分(List 2-(1))は,List 1-(1)と比べて,非常に見にくいものにな
っている。これは,エラー検査を行うif-else文で各処理が分断されているからである。そして,エラ
ー処理を行っているList 2-(2)の部分も,どこでどのエラーを処理しているか非常に分かりづらくな
っている。
このように,if文でエラーの検査を行う古典的な手法は,本来の処理の記述を複雑にしてしまうと
いう問題をかかえていると言える。
ところが,今回学習する「例外」の仕組みを使うと,下図右のように通常処理とエラー処理部分が
綺麗に分離されて分かりやすくプログラムが書けるようになるのである。
●どこでエラー処理を行うか
エラーが起こるのは,プログラムを実行しているときである。つまり,メソッドを実行しているとき
である。今ここで,あるメソッドを実行中に,エラーが起こったとしよう。このとき,そのメソッドで
完全にエラー対処を行うことができるかというと,かならずしもそうではない。場合によっては,呼び
出し元のメソッドにエラー処理を頼まなくてはならない場合もある。
例として,メソッドm1( )がメソッドm2( )を呼び,さらにメソッドm2( )がメソッドm3( )を呼んでい
る状況を考えてみよう。たとえば,
class A { void m1( ) { m2( ); } void m2( ) { m3( ); } void m3( ) {} }というような場合である。下図Fig.1は,この状況でm3( )でエラーが起こった様子を示している。
●エラー内容を通知する方法
では,メソッドはどのような手段でエラーが起こったことを自分を呼び出したメソッドに通知すればいい
のだろうか。
古典的な手法では,下図List 3のようにメソッドの返り値をエラー通知に使う。List 3-①ではエラー
内容を表すint型定数(エラーコード)を定義している。メソッドm3( )は,エラーが起こると,aErrorというエラーコード
を返値として返す(List 3-②)。m3( )を呼び出しているm2( )は,m3( )の返すエラーコードを調べて(List 3-③),
エラーが発生していたら,できるだけのエラー処理をしてから,呼び出し元に対してエラーコードを返値として返す
(List 3-④)。同様に,m1( )は,m2( )を呼び出しているところで,m2()が返してきたエラーコードを調べて(List 3-⑤),
エラーが起こっていたら,エラー処理を行う(List 3-⑥)。
このように,メソッドの返り値を使ってエラーを呼び出し元に通知する古典的な方法には,以下のよ
うな欠点がある。
・第1に,メソッドの返り値をもっぱらエラー通知に使用することになってしまうこと。
※返り値には,エラーコード以外の値を返さなければならないメソッドもたくさんる。
・第2に,前述したように,メソッドの返り値を常にif文で調べなければならないので,処理の記述が複雑になってしまう。
・第3に,エラーの内容を詳しく使えるのが難しい
※List 3の例では,整数値でエラーの内容を伝えることができるが,より詳しいエラー
の情報(たとえば,エラーが起こった状況などに関する情報)が欲しい場合には,整数
定数では不可能である。詳しいエラー情報を得るためには,エラーとして返す値をオ
ブジェクトにすれば解決する。しかし,エラーが起こったときはあたりまえとして,
エラーが起こらなかったときも,オブジェクトをいちいちを生成して返すのでは,実
行効率が悪くなる。
以上のように,古典的なエラー処理の方法は,様々な欠点を持ってる。このような欠点を解消したエラー
通知とエラー処理の方法,それがJavaが備えている例外処理である。次に,例外処理メカニズムの概要を説
明する。