The Java Language Specification 11.2.2 makes a difference between final and not final exceptions:
A throw statement (§14.18) whose thrown expression has static type E and is not a final or effectively final exception parameter can throw E or any exception class that the thrown expression can throw.
[...]
A throw statement whose thrown expression is a final or effectively final exception parameter of a catch clause C can throw an exception class E iff:
- E is an exception class that the try block of the try statement which declares C can throw; and
- E is assignment compatible with any of C's catchable exception classes; and
- E is not assignment compatible with any of the catchable exception classes of the catch clauses declared to the left of C in the same try statement.
Interestingly, JLS 14.20 also says:
In a uni-catch clause, an exception parameter that is not declared final (implicitly or explicitly) is considered effectively final if it never occurs within its scope as the left-hand operand of an assignment operator.
In other words, if you don't reassign the e
of your catch statement (like e = new SomeOtherException();
), it is implicitly declared final.
So I can only conclude that it does not make a difference, unless the exception is modified in the catch block and the only example I can come up with is:
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
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…