Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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

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

I presume the final is for performance. As per the title, since there's rarely (ever?) any reason to modify an Exception that's already been thrown, should they always be final?

If so, isn't this something that could be done by the compiler? Or is it done by the compiler and adding the final manually has no impact at all?

like image 878
Matthew Avatar asked Aug 21 '12 09:08

Matthew


People also ask

Why we should not catch exception?

Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. Also when you catch all exceptions, you may get an exception that cannot deal with and prevent code that is upper in the stack to handle it properly.

Is final keyword useful?

The final keyword is a non-access modifier used for classes, attributes and methods, which makes them non-changeable (impossible to inherit or override). The final keyword is useful when you want a variable to always store the same value, like PI (3.14159...). The final keyword is called a "modifier".

What purpose do the keywords final finally and finalize fulfill?

C++ Programming A final class cannot be inherited, a final method cannot be overridden and a final variable cannot be reassigned. The finally keyword is used to create a block of code that follows a try block. A finally block of code always executes, whether or not an exception has occurred.

How do you catch exceptions without trying?

throws: The throws keyword is used for exception handling without try & catch block. It specifies the exceptions that a method can throw to the caller and does not handle itself.


2 Answers

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
    }
}
like image 158
assylias Avatar answered Oct 11 '22 12:10

assylias


I believe final is useful when the code which could use it is too long to easily read and understand. e.g. I would make fields final where possible to ensure they are assigned correctly in constructors and not modified anywhere in the class.

Using final for a catch clause is unlikely to help much as a) the value is guaranteed to be set b) the code using it should be short, c) its very rare to modify it anyway.

There is nothing stopping you from doing it however.

like image 22
Peter Lawrey Avatar answered Oct 11 '22 11:10

Peter Lawrey