ひまlab

ひまな時になんか書く。

例外をフロー制御に使用すべきでない理由について

コーディングにおいて、例外をフロー制御に使用すべきでないと言われます。
ただ、なぜ使用すべきでないかがあまり語られない気がするので、考えてみました。

例外をフロー制御に使用した例(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を使うとか