Java 言語仕様 11.2.2では、最終的な例外と最終的でない例外に違いがあります。
スローされた式が静的型 E を持ち、最終または実質的に最終の例外パラメーターではない throw ステートメント (§14.18) は、E またはスローされた式がスローできる例外クラスをスローできます。
[...]
スローされた式が catch 句 C の最終または実質的に最終の例外パラメーターである throw ステートメントは、次の場合に例外クラス E をスローできます。
- E は、C を宣言する try ステートメントの try ブロックがスローできる例外クラスです。と
- E は、C のキャッチ可能な例外クラスのいずれかと互換性のある代入です。と
- E は、同じ try ステートメントで C の左側に宣言されている catch 句のキャッチ可能な例外クラスのいずれとも代入互換性がありません。
興味深いことに、JLS 14.20には次のようにも書かれています。
uni-catch 句では、final として (暗黙的または明示的に) 宣言されていない例外パラメーターは、代入演算子の左側のオペランドとしてスコープ内で発生しない場合、実質的に final と見なされます。
e
つまり、 catch ステートメント ( など) を再割り当てしない場合e = new SomeOtherException();
、それは暗黙的に final として宣言されます。
したがって、catch ブロックで例外が変更されていない限り、違いはないと結論付けることができます。私が思いつく唯一の例は次のとおりです。
public void method1() throws IOException {
try {
throw new IOException();
} catch (Exception e) { // e is not modified in catch => implicitly final
throw e; //compiles OK
}
}
//it works because method1 is semantically equivalent to method2:
public void method2() throws IOException {
try {
throw new IOException();
} catch (final Exception e) {
throw e;
}
}
public void method3() throws IOException {
try {
throw new IOException("1");
} catch (Exception e) {
e = new IOException("2"); //e modified: not implicitly final any more
throw e; //does not compile
}
}