![]() ![]() ![]() ![]() |
例外を使用したエラー処理 |
Java 言語では、ランタイム例外をキャッチしたり指定するメソッドが必要ないので、プログラマはランタイム例外だけをあげるコードを作成したり、すべての例外をRuntimeExceptionのサブクラスとして作成しようとする。 この両者のプログラミングの近道により、プログラマは下記のようなコンパイラのしつこいエラーを気にせず、
InputFile.java:8: Warning: Exception java.io.FileNotFoundException must be caught, or it must be declared in throws clause of this method. fis = new FileInputStream(filename); ^例外をキャッチしたり指定することに煩わされずに Java コードを書くことができる。 これはプログラマにとって便利に思えるかもしれないが、Java のキャッチや指定の条件の主旨を逸脱することで、これによってこうしたクラスを使用したプログラマに問題が起きることになる。
なぜ Java の設計者は、メソッドに,メソッドの適用範囲内であげられる確認した例外でキャッチしていない例外をすべて指定させるようにしたのか?それは,メソッドがあげる例外は、実際にはメソッドの public なプログラムインターフェイスの一部であるべきで、メソッドの呼び出し側は、これらの例外について何を行うべきかを理性的にかつ意識的に判定するために、メソッドがあげる例外について知っていなくてはならない。 したがって,メソッドがあげる例外は、そのパラメータと返り値と同じようにプログラムインタフェースの一部として記述される。
次の質問は「メッソドがあげる例外を含む,メソッドの API を記述するのがよいことであるなら、ランタイム例外もなぜ指定しないのか?」となるかもしれない。
ランタイム例外は、例外がランタイムシステムによって検出された問題であることを表す。 これには、算術例外(ゼロ除算など)、ポインタ例外(null 参照を通してオブジェクトにアクセスしようと試みるなど)、指標付け例外(あまりにも大きすぎる、あるいは小さすぎるインデックスを通して、配列要素をアクセス使用と試みるなど)が含まれる。
ランタイム例外はプログラムの至る所で発生し、典型的なプログラムには非常に多く発生する。 一般に、ランタイム例外を確認するコストは、それらをキャッチしたり指定する利点を上回る。 したがって、ランタイム例外をキャッチしたり指定することは可能であるが、コンパイラはこうしたことを要求しない。
確認した例外は、呼び出し側が制御できず、呼び出し側が知る必要のある例えば、ファイルシステムがフルである、リモート側端末がコネクションを閉じた、あるいはアクセス権がこの動作を許可しないなどの操作についての役立つ情報を,指定された要求とこの例外の型が合致した場合に表示する。
例外の指定を行いたくないので、 RuntimeException をあげるか、あるいは RuntimeException のサブクラスを作成するとしたら、何を獲得できるだろうか。 単に、例外の指定を行なわずに例外をあげる能力が得られる。 換言すれば、メソッドがあげる例外を文書で説明するのを避けるための方法である。 こうすることがどんな場合に適切なのか? メソッドの振る舞いを文書で説明するのを避けるのが、どんな場合に適切なのか? 答えは「そういう場合はほとんどない」である。
経験則:
- メソッドは仮想マシン実行時にエラーと出会うと、エラーを検出して RuntimeException をあげることができるが、一般には仮想マシンに検出させてあげさせる方が簡単である。 ユーザが、作成するメソッドは通常 RuntimeExceptions ではなく、Exceptions をあげる。
- 同様に、仮想マシン実行時にエラーを作成している時(そんなことはしないが)は、RuntimeException のサブクラスを作成する。 さもなければ Exception のサブクラスを作成する。
- ランタイム例外を指定することにこだわりたくないので、ランタイム例外をあげたり、RuntimeException のサブクラスを作成してはいけない。
![]() ![]() ![]() ![]() |
例外を使用したエラー処理 |