JPCERT コーディネーションセンター

ERR07-J. RuntimeException, Exception, Throwable をスローしない

メソッドは RuntimeExceptionExceptionThrowable をスローしてはならない。これらの例外を処理するには、RuntimeException をキャッチする必要があるが、これは「ERR08-J. NullPointerException およびその親クラスの例外をキャッチしない」で禁止されている。また、RuntimeException をスローすると分かりにくいエラーにつながることがある。たとえばメソッドの呼出し側は例外がスローされた原因を調べることができず、例外状態から回復できないかもしれない。

Exception もしくは RuntimeException の特定のサブクラスの例外であれば、メソッドはスローしてもよい。単一のthrow文に対して専用の例外クラスを作成することも許される。

違反コード

以下のコード例の isCapitalized() メソッドは、引数に文字列を取り、先頭の文字が大文字、2文字以降がすべて小文字、というパターンである場合に true を返す。また、引数に null が渡されると、RuntimeException をスローする。

boolean isCapitalized(String s) {
  if (s == null) {
    throw new RuntimeException("Null String");
  }
  if (s.equals("")) {
    return true;
  }
  String first = s.substring(0, 1);
  String rest = s.substring(1);
  return (first.equals(first.toUpperCase()) &&
          rest.equals(rest.toLowerCase()));
}

isCapitalized()メソッドの呼出し側でRuntimeExceptionがスローされたかどうかを判断するためには、「ERR08-J. NullPointerException およびその親クラスの例外をキャッチしない」に違反せざるをえない。

適合コード

以下の適合コードでは、特定の例外条件を示すために NullPointerException をスローしている。

boolean isCapitalized(String s) {
  if (s == null) {
    throw new NullPointerException();
  }
  if (s.equals("")) {
    return true;
  }
  String first = s.substring(0, 1);
  String rest = s.substring(1);
  return (first.equals(first.toUpperCase()) &&
          rest.equals(rest.toLowerCase()));
}

入力がnullかどうかのチェックは冗長である。このチェックを削除したとしても、入力snullである場合にはs.equals("")の呼出しでNullPointerExceptionがスローされる。しかし、明示的にnullチェックを行うコードを書くことで、プログラマの意図が明確になる。コードが複雑になるほど、不変条件のチェックと適切なthrow文を明示的に書くことが重要になるであろう。

違反コード

以下の違反コード例では、doSomething メソッドの宣言において、throws 節に Exception クラスを指定している。

private void doSomething() throws Exception {
  //...
}
適合コード

以下の適合コードでは、例外条件をより明確に表す例外クラスとして IOException を指定している。

private void doSomething() throws IOException {
  //...
}
例外

ERR07-EX0: セキュリティポリシーに適合するために例外を無害化するようなクラスでは、無害化したい特定の例外をキャッチし、代わりに、より一般的な例外をスローすることが許される。その場合、セキュリティポリシーの内容にもよるが、RuntimeExceptionExceptionThrowableをスローすることがある。

リスク評価

runtimeExceptionExceptionThrowableをスローすると、意図した例外クラスだけをキャッチするはずが、意図しない例外クラスまでキャッチしてしまう。

ルール 深刻度 可能性 修正コスト 優先度 レベル
ERR07-J P6 L2
関連ガイドライン
MITRE CWE CWE-397. Declaration of throws for generic exception
参考文献
[Goetz 2004b]  
[Tutorials 2008] Unchecked Exceptions – The Controversy
翻訳元

これは以下のページを翻訳したものです。

ERR07-J. Do not throw RuntimeException, Exception, or Throwable (revision 94)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter