プログラミング応用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文でエラーの検査を行う古典的な手法は,本来の処理の記述を複雑にしてしまうと
いう問題をかかえていると言える。



ところが,今回学習する「例外」の仕組みを使うと,下図右のように通常処理とエラー処理部分が
綺麗に分離されて分かりやすくプログラムが書ける
ようになるのである。

use_exception

 


●どこでエラー処理を行うか

 エラーが起こるのは,プログラムを実行しているときである。つまり,メソッドを実行しているとき
である。今ここで,あるメソッドを実行中に,エラーが起こったとしよう。このとき,そのメソッドで
完全にエラー対処を行うことができるかというと,かならずしもそうではない。場合によっては,呼び
出し元のメソッドにエラー処理を頼まなくてはならない場合もある。

 例として,メソッドm1( )がメソッドm2( )を呼び,さらにメソッドm2( )がメソッドm3( )を呼んでい
る状況を考えてみよう。たとえば,

class A {
    void m1( ) { m2( ); }
    void m2( ) { m3( ); }
    void m3( ) {}
}
というような場合である。下図Fig.1は,この状況でm3( )でエラーが起こった様子を示している。
m3( )は,起こったエラーに対して完全な処理はできず,できるだけのことをして,エラーが起こった
ことを呼び出し元のm2( )に通知して,m2( )に残りのエラー処理をまかせる。


 m3( )からエラー処理をまかされたメソッドm2( )も自分ではエラー処理を完全に行うことはできない
ので,呼び出し元のメソッドm1( )にエラーを通知して,残りのエラー処理をm1( )にまかせる
。メソッド
m1( )は,受け取ったエラー通知にしたがってエラーを処理することになる。



 このように,エラーが発生した場所とエラーを処理する場所は,異なっている場合がある。このよう
なケースに対処するためには,エラーを呼び出し元に通知する手段が必要になる。

 


●エラー内容を通知する方法

 では,メソッドはどのような手段でエラーが起こったことを自分を呼び出したメソッドに通知すればいい
のだろうか。

 古典的な手法では,下図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が備えている例外処理である。次に,例外処理メカニズムの概要を説
明する。


次に進む