次のコードが提供されている状況を考えてみましょう。
public void delete() throws IOException, SQLException { // Non-Compliant
/* ... */
}
ここでの危険は、呼び出すために記述するコードが次のようにdelete()
なることです。
try {
foo.delete()
} catch (Exception e) {
/* ... */
}
これも悪いです。そして、ベースの例外クラスをキャッチするフラグを立てる別のルールでキャッチされます。
重要なのは、他の場所に悪いコードを書きたくなるようなコードを書かないことです。
あなたが遭遇しているルールはかなり一般的なものです。 Checkstyleの設計ルールには次のようなものがあります。
ThrowsCount
throwsステートメントを指定されたカウント(デフォルトでは1)に制限します。
根拠:例外はメソッドのインターフェースの一部を形成します。あまりにも多くの異なるルートの例外をスローするようにメソッドを宣言すると、例外処理が面倒になり、catch(Exception ex)のようなコードを記述するなどのプログラミングプラクティスが貧弱になります。このチェックにより、開発者は例外を階層に入れ、最も単純なケースでは、呼び出し元が1種類の例外のみをチェックする必要がありますが、必要に応じてサブクラスを具体的にキャッチできます。
これは問題を正確に記述し、問題は何であり、なぜそれをしてはいけないかです。多くの静的分析ツールが識別してフラグを付けることは、広く受け入れられている標準です。
そして、あなたは言語設計に従ってそれをするかもしれません、そしてそれが正しいことである時があるかもしれませんが、それはあなたが見て、すぐに行くべきものです。誰もが決して絶対catch (Exception e) {}
に規律を守らない内部コードにとっては受け入れられるかもしれませんが、特に内部の状況では、多くの場合、私は人々がコーナーを切るのを見てきました。
クラスを使用している人に悪いコードを書きたがらせないでください。
Java SE 7以降では、1つのcatchステートメントで複数の例外をキャッチできるため、この重要性が低下していることを指摘しておく必要があります(複数の例外タイプをキャッチし、Oracleの改善されたタイプチェックで例外を再スロー)。
Java 6以前では、次のようなコードになりました。
public void delete() throws IOException, SQLException {
/* ... */
}
そして
try {
foo.delete()
} catch (IOException ex) {
logger.log(ex);
throw ex;
} catch (SQLException ex) {
logger.log(ex);
throw ex;
}
または
try {
foo.delete()
} catch (Exception ex) {
logger.log(ex);
throw ex;
}
Java 6のこれらのオプションはどちらも理想的ではありません。最初のアプローチはDRYに違反しています。複数のブロックが同じことを何度も何度も繰り返します-例外ごとに1回。例外をログに記録して再スローしたいですか?OK。各例外に対して同じコード行。
2番目のオプションは、いくつかの理由により悪いです。まず、すべての例外をキャッチしていることを意味します。Nullポインターがそこにキャッチされます(そうすべきではありません)。さらに、あなたはコードを使用している人々が強制されているため、スタックをさらに混乱させるException
メソッドシグネチャが再スローされることを意味deleteSomething() throws Exception
します。catch(Exception e)
Javaの7では、これがないと、あなたが代わりに行うことができるので重要:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
1の場合はさらに、タイプはチェックしないスローされた例外の種類をキャッチ:
public void rethrowException(String exceptionName)
throws IOException, SQLException {
try {
foo.delete();
} catch (Exception e) {
throw e;
}
}
タイプチェッカーは、それe
がタイプまたはのみであることを認識します。私はまだこのスタイルの使用についてあまり熱心ではありませんが、Java 6の場合ほど悪いコードを引き起こしているわけではありません(例外が拡張するスーパークラスであるメソッドシグネチャを強制する場合)。IOException
SQLException
これらのすべての変更にもかかわらず、多くの静的解析ツール(Sonar、PMD、Checkstyle)がJava 6スタイルガイドを施行しています。それは悪いことではありません。私はこれらがまだ実施されるという警告に同意する傾向がありますが、あなたのチームがそれらに優先順位を付ける方法に従って、それらの優先度をメジャーまたはマイナーに変更するかもしれません。
例外は、オンまたはオフする必要がある場合は...それは問題であるG R 電子トンの 議論 1は、簡単に、引数の各側面を取って無数のブログ記事を見つけることができるということを。ただし、チェックされた例外を使用している場合は、少なくともJava 6で複数の型をスローすることは避けてください。