例外をフロー制御に使用すべきでない理由について
コーディングにおいて、例外をフロー制御に使用すべきでないと言われます。
ただ、なぜ使用すべきでないかがあまり語られない気がするので、考えてみました。
例外をフロー制御に使用した例(Java)
Javaでは、文字列を数値型に変換できるかを判定する仕組みが、標準では存在しない*1。
そのため、以下の様な実装で判定することがある。
// 文字列がintに変換可能か判定する。 // true:変換できる, false: 変換できない private boolean isConvertibleToInt(String objective) { // intに変換し、例外が発生しなければ変換可能と判断する try { Integer.parseInt(objective); } catch (NumberFormatException e) { return false; } return true; }
例外をフロー制御に使用すべきでない理由
なぜかと考えた時に、行き着いた答えは次の2(+1)つ。
1. 例外が"例外"でなくなるため
例外が正常な処理の中で発生することになる。
そのため、正常なのに例外が発生する。
例外が"例外"でなくなり結果として、例外が無視されてしまう。
上の例では、「NumberFormatException」が発生しても問題がないため、たいてい無視される。
try { Integer.parseInt(objective); } catch (NumberFormatException e) { return false; }
2. 処理結果が例外に依存するため
上の例では変換できないという結果が「NumberFormatException」が発生することに依存する。
これでは、「NumberFormatException」が別の例外に変わった時に正しく動かなくなってしまう。
- たとえば、Integer.parseInt()にnullが渡された時に、NumberFormatExceptionでない例外が発生するようになるかもしれない。
- その時は、文字通り"例外"で落ちることになるので、良いといえば良いのだけど・・。
+1. 例外が発生する場合のフローが、わかりにくい。
例外処理に飛ぶことが、コードに書かれていないため場合によってはGOTO以上に可読性を落とす。
例外とGOTOの違いが、(自分が)整理できていないため、詳しくは書けない。
*1:知らないだけかもしれない。Commonsを使うとか