Javaのチェック例外はクソ仕様

Java言語のチェック例外は本当にGood Partなのか?というエントリーを読んで自分の考え方を簡単にまとめておこうと思う。
まず、チェック例外自体はJavaの『あまり良くない仕様』とみるのが体勢であると思う。自分もどちらかといえば、『なるべく実行時例外で』という派。とはいえ、『クソ仕様なんでチェック例外はまったく使うべきではない』派ではなく、『必要に応じて使い分ける』派。そもそもクソ仕様とdisるくらいならクソ言語なんか使わない方が幸せ。

まずチェック例外自体に関する問題を改めて整理する。

  • いちいち定義するのがクソ面倒
  • 常にtry-catchかthrows句を強制するのでクソウザい
  • 横断的に処理しにくい
  • 大規模プロジェクトになればなるほど、例外に関するスキルがないクソ人ばかり

これらについては散々議論されているだろうし、愚痴になるだけだと思うので割愛。

で、自分はどうして『必要に応じて使い分ける』のか?自分としてはチェック例外はチェックしなければならない準正常系の戻り値という意味が強いから。

Throwable

そもそも例外(Exception)という言葉がまずいと思う。誰もが知っているようにExceptionはThrowableのサブタイプ。そしてメソッドが終了する条件に関する言語仕様としては3つある。

  • return文で適切な値が返される
  • throw句でThrowableのサブクラスが投げられる
  • メソッドが最後の行まで実行される(戻り値がvoidの場合のみ)

本来、return と throwはそれほど遠い存在ではなく、Throwableは戻り値の一種。return とthrowで異なるのは実行側のコードであり、returnはそのままステートメントが実行されていくのに対し、throwはThrowableが伝搬されていくという違い。この辺を勘違いしていて、例外=怖いものと考えている人は意外と多いというのが開発現場の実情。

throws

では、チェック例外として定義するかどうか?チェック例外とした場合には、throws句に定義するかtry-catchでハンドリングするかのどちらかを強制するのがJavaの仕様。なので、自分のスタンスは明示的に宣言が必要なthrowであればチェック例外にする

言い換えれば、仕様として明確にしたいかどうかだと思う。throws句にあってJavaDocも書いてあれば後で読む時に楽だし、例外ハンドリングを忘れるという事も防げる。それって素晴らしい機能、チェック例外は失敗では断じてない。ただ、ウザいだけ。それも、とても、とてもウザいだけ。素晴らしい仕様だけど同時にクソ仕様。

勿論、「面倒だし、下手にcatchされると大変なので全部非チェック例外で…」という場面は多いので現場のレベルに合わせるのがベスト。