例外を処理せず強制終了の妥当な方法の検討

今日は特にネタもないので例外のお話。プログラマ=ユーザな信頼性とかいらないプログラムを書いていると例外処理ほど鬱陶しいものはありません。しかしJava言語は大変マジメなやつで、RuntimeExceptionを除き例外処理を書かないとコンパイルすら通りません。例外を処理しない場合にはthrows宣言を上位に伝播せねばならず、呼び出し階層が深くなるとウザ過ぎです。

で、よくある間違いは、例外をcatchするだけして何もしないというやつです。これは最悪です。例外が発生したことがわからず、後々変なところで死んで原因究明が困難になるだけです。プログラムに永続性とか必要なければ今すぐ強制終了すべきです。

サンプルプログラムなんかでよく見かけるのはスタックトレースを表示してからreturnまたはexitするやつです。原因はわかるけど、returnはプログラムを終了しないし、boolかなんかを返して呼び出し元で成功か失敗をチェックする必要が出てきます。exitはfinallyを実行しません。ファイルの入出力とかやってるとクローズされるのはgc任せでちょっと気持ち悪いです。

最も簡単で妥当な強制終了方法は、全部RuntimeExceptionにしてしまえという発想。IOExceptionとか例外をcatchしたらRuntimeExceptionまたはその派生クラスをthrowで新しく投げればよい。どんな例外でもRuntimeExceptionに例外翻訳してしまえばthrows宣言を強制されることはなく、catchしなければmainまでスタックを遡って強制終了し、スタックトレースを表示してから死ぬ。このとき、RuntimeExceptionは引数に原因となった例外であるthrowableを渡せるのでこれを使えばcaused byとしてRuntimeExceptionの元になった本来の例外が表示されるので原因もわかる。プログラム初期化時のパラメータチェックとかも失敗時にRuntimeExceptionまたはその派生クラスを投げるようにすれば例外が出たら勝手に遡って死ぬので関数が成功したか失敗したかのboolを返す必要もなく呼び出し元のコードで戻り値チェックやエラー処理が消えクリーンになりかつ、しかもfainallyは例外時でもちゃんと実行される。

なんでもかんでもRuntimeExceptionに例外翻訳してしまうという力技は、原因だけわかれば例外から回復するつもりのない自分用プログラムの場合なかなかリーズナブルな方法ではないかなぁという話。throws書くのめんどくさいよねとか思ったことがある人は心当たりがあるはず。