タイプ別例外の定義
Javaプログラマであれば例外クラスを一度は扱ったことがあるでしょう。数ある例外クラスの中でもぜひ理解しておきたい4クラスとして、「Throwable」「Exception」「RuntimeException」「Error」があります。
いずれもjava.langパッケージのクラスですが、これらのクラスは互いに継承関係にあります。
すべての例外クラスの頂点にあるのがThrowableクラスです。つまりThrowableクラスのサブクラスはすべて例外クラスということになります。いい換えれば例外クラスでありたいならばThrowableクラス、もしくはそのサブクラスを継承しなければなりません。この階層関係は、言語仕様にも明確に規定されています。
The possible exceptions in a program are organized in a hierarchy of classes, rooted at class Throwable, a direct subclass of Object. The classes Exception and Error are direct subclasses of Throwable. The class RuntimeException is a direct subclass of Exception.
(訳:プログラム中で発生する可能性のある例外は、Objectの直接のサブクラスであるクラスThrowableを頂点としたクラス階層に組織化される。クラスExceptionとErrorはThrowableの直接のサブクラスである。クラスRuntimeExceptionはExceptionの直接のサブクラスである)。
このように固有のクラス名を出して継承関係まで言及しているのは、Javaの言語仕様においても他に例がありません。その理由は、コンパイラや実行環境がこの階層関係の意味付けを頼りに動作しているからです。ではこの階層関係にはどのような意味があるのでしょうか。
例外クラスは大別すると「コンパイルチェックされるクラス(検査例外)」と「コンパイルチェックされないクラス(非検査例外)」の2つのタイプに分類されます。
前者の検査例外というのは皆さんもご存知のtry〜catchを強制される例外クラスです。つまり例外の発生を意識しハンドリングするプログラムを書かないとコンパイルを通すこともできません。
一方後者の非検査例外というのはどういうものでしょうか。誤解を恐れずにいうならば、予測の付かない例外であり、予測が付かないからチェックはしないというものです。RuntimeException系の代表的なクラスにNullPointerExceptionクラスがあります。この例外クラスは参照先が存在しない場合に発生する例外であり、いつどこでも発生する可能性があることは皆さんもよくご存知でしょう。この例外の捕捉(catch)を強制されたらどうなるか想像してください。ほぼすべてのコードがtry〜catchに埋もれてしまうことになってしまいます。この点についても言語仕様には記載されています。
The runtime exception classes (RuntimeException and its subclasses) are exempted from compile-time checking because, in the judgment of the designers of the Java programming language, having to declare such exceptions would not aid significantly in establishing the correctness of programs.
(訳:実行時例外クラス(RuntimeExceptionとそのサブクラス)は、こういった例外宣言を強制してもJavaプログラムの正当性を確立するための著しい助けにはならないであろう、というJava設計者達の判断によりコンパイル時にはチェックされない)。
またエラークラス(Errorとそのサブクラス)も同様にチェックされることはありません。これも言語仕様上に同様の理由が記載されているのでぜひ自身の目で確認してみてください。
ところでこのErrorクラスはクラス階層上Exceptionクラスと並列に配置されています。RuntimeExceptionクラスはExceptionクラスのサブクラスにも関わらずErrorクラスはExceptionクラスのサブクラスではありません。読者の皆さんは不思議に思ったことはないでしょうか? 些細なことかもしれませんが、この理由についても言語仕様をみることでJava設計者達の配慮が伺えます。
The class Error is a separate subclass of Throwable, distinct from Exception in the class hierarchy, to allow programs to use the idiom:
(訳:クラスErrorは、以下のような慣用句を記述できるようにするため、Throwableのクラス階層中にExceptionとは別のサブクラスとして置かれている:)
} catch (Exception e) {
to catch all exceptions from which recovery may be possible without catching errors from which recovery is typically not possible.
(訳:これによって、通常は回復処理が不可能なエラーをキャッチすることなく、回復処理が可能なすべての例外をキャッチすることができるようになる)。
このように言語仕様には仕様的なものの他にも、その仕様に至った背景や経緯、設計者の想いなども記されているのです。それらを知ることにより表面的な理解からの脱却をはかるいい手助けになると思います。
最後に、規約には書かれていない、言語仕様の裏の世界をみていきましょう。 次のページ