Is there ever a reason to not use the final keyword when catching an exception?

后端 未结 5 944
萌比男神i
萌比男神i 2020-12-16 12:03

I\'ve seen some code as below in some example BlackBerry Java classes:

try
{
    // stuff that will throw an exception
}
catch(final Exception e)
{
    // de         


        
5条回答
  •  臣服心动
    2020-12-16 12:24

    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
        }
    }
    

提交回复
热议问题