Javaに限らず、最近の言語には必ず付いてくる例外処理。
しかし、これを使いこなすにはかなりの経験が必要になります。
PMD : EmptyTryBlock
try〜catch構文のtryブロックが空。
以前記述してあったロジックをコメントアウトした場合などによく起こります。
try {
// 空、もしくは全てがコメントアウトされている
}
空のifブロック と同様。このような場合、tryブロック毎コメントアウトしましょう。
PMD : EmptyCatchBlock
FindBugs : DE: Method might drop exception
try〜catch構文のcatchブロックが空。
これは、ここでcatchした全ての例外を「捨てて」しまうことになります。
よっぽどの事が無い限り、例外情報を捨てる理由は無いはずです。
try {
FileInputStream fis = new FileInputStream("/tmp/bugger");
} catch (IOException ioe) {
// 空のcatchブロック
}
PMD : EmptyFinallyBlock
try〜catch〜finally構文のfinallyブロックが空。
try {
...
} finally {
// 空のfinallyブロック
}
空のtryブロック などと同様です。
finallyブロックは、「途中で例外が発生した場合にも常に実行させたい処理」を
記述する場所です。
ここに return 文を配置するのは構文としては間違ってはいませんが
例外が発生したときに「その例外を捨てて」return文が実行されてしまいます。
ですから、finallyブロックにreturn文を記述してはいけません。
try {
...
} finally {
return OK; // try句で発生した例外情報が捨てられてしまう
}
Throwable および Exception は、全ての例外をカバーするので
非常に便利なのですが、考え方を変えれば「手抜き」には間違いないので
きちんとした例外処理を記述することを心掛けましょう。
PMD : AvoidCatchingThrowable / SignatureDeclareThrowsException
CheckStyle : IllegalCatch
これも同様に、Exceptionを直接スローするのは止めましょう。
他にも、RuntimeException や Error もスローすべきではありません。
PMD : AvoidThrowingRawExceptionTypes
CheckStyle : IllegalThrows
こんなメソッドを見たことがあるでしょうか。
public void bar() throws IOException, ServletException,
SQLException, ParseException, SocketException {
...
}
このメソッドをコールした箇所では、これら全ての例外をキャッチする必要があります。
多くの人はこれを嫌い、Exception でまとめてキャッチするという
アンチパターンに走りがちです。
こういった事を避けるために、一つのメソッドからスローする
例外の数は制限しましょう。
2つ程度が妥当な線でしょうか。
CheckStyle : ThrowsCount
private void bar() throws FileNotFoundException, IOException;
FileNotFoundException は IOException のサブクラスなので
以下のようにしても同じです。
private void bar() throws IOException;
あえて FileNotFoundException をスローすることを伝えたいのならばIOException の方を別なものに変えましょう。
private void bar() throws FileNotFoundException, EOFException;