2つのコードサンプルの動作に違いはありません。(特に、スタックトレースは、例外がスローされたときではなく、作成されたときに記録されるため、再スローされた例外には元のスタックトレースが残ります)。したがって、通常、人々はより単純なイディオムを使用します。
それは、再スローがその用途を持っていないということではありません。たとえば、FooBarExceptionsを除くすべての例外を処理する場合は、次のように記述できます。
try {
// bad code
} catch (FooBarException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
}
または、例外を処理する決定が単にその型をチェックするよりも複雑な場合は、単にそれをキャッチし、処理できないことが判明した場合は再スローできます。
for (int attempts = 0; attemps < 6; attempts++) {
try {
return crankyMethod();
} catch (Exception e) {
if (fatal(e)) {
throw e;
} else {
// try again
continue;
}
}
}
次の例のように、人々が再スローと言うとき、別の例外をスローすることを意味するものもあることに注意してください。
for (int i = 0; i < array.length; i++) {
try {
process(array[i]);
} catch (Exception e) {
throw new RuntimeException("Could not process element at index " + i, e);
}
}
このパターンの利点は、関連する可能性のある追加情報(上記の例では、どのデータを処理できなかったか)で元の例外を装飾することです。元の例外は新しい例外のコンストラクターに渡されるため、そのスタックトレースは失われないことに注意してください。