The Oracle documentation on the multi-catch feature added to Java 7 states that the exception parameter in the catch
clause is implicitly final
.
My question is: what's the point of such restriction? Because i can't seem to find a single crucial improvement it brings. Marking a reference object as final
only protects the reference itself from being modified, not the object it references, and one is never prohibited to create another reference and modify it in whatever way they want.
A somewhat relevant question on SO discusses the reasons why modifying the exception reference in a catch
clause is not the wisest thing to do, but it relates to any use of the catch
clause, not just the multi-catch form of it. So why does Java make an, ahem, exception for the multi-catch and treat it in a special way?
In the uni-catch clause, you are free to re-assign the exception object. For example, this works fine:
try {
... // code that can throw IOException or some user-defined ParserException
} catch(IOException) {
e = new IOException(); // this is acceptable (although there is no point in doing it)
e.printStackTrace();
}
The compiler knows for sure that the thrown object is of type IOException
.
However, in the multi-catch clause, you can have something like:
try {
... // code that can throw IOException or some user-defined ParserException
} catch(IOException | ParserException e) {
e = new IOException(); // this is NOT acceptable -- e may reference a ParserException
e.printStackTrace();
}
In this case, the compiler has no idea which type the exception is at compile-time, so assigning a new IOException
to a variable that can reference either an IOException
or ParseException
should not be allowed. Added to that is the lack of use-cases for assigning to the exception variable in the first place. Therefore it makes perfect sense to make the variable implicitly final
and avoid all of this confusion. If you really need to assign to the variable, you can switching to the old way of writing sequence of catch
blocks.