What does "final" do in the following Java expression?
catch (final SomeExceptionType e)
What does "final" do in the following Java expression?
catch (final SomeExceptionType e)
It basically means:
Catch "SomeExceptionType" into the variable "e" with the promise that we won't assign a different exception to "e" during the processing of the exception.
Mostly this is overkill, as if I'm catching an exception into a temporary variable name (e only is valid for the exception handling block), I don't have to police myself so strictly as to not trust myself to assign a different (possibly created) exception to the same variable name.
That said, perhaps this block is heavily maintained by a team of different-minded individuals, and one just wanted to be VERY sure that e was the original captured exception.
---- Edited in response to commentary ----
I can't think of a really excellent reason to do this. Since "e" is not a member (static or otherwise) the name "e" won't be used by the class file post-compilation. Another way of stating this is that when you enter the exception handling block of JVM bytecode, the object won't be assigned to any of the member names accessible by the JVM processing frame, it will be pushed to the internal processing stack of the Thread's current frame.
Even if two threads had access to the same Object, each thread would have it's own frame, so the compiler removed "e" name from one frame's internal stack couldn't be altered by the other thread.
With that in mind, the only benefit of declaring "e" final is to make sure that future coders don't accidentally set "e" after entering the block. Perhaps they meant to make the code more robust in a multi-threaded environment, but temporary variables (those with names that only are valid in the block) don't have names post-compilation, they are pushed onto the frame's stack.
That's why
public int safe() {
int x = 5;
x = x + 5;
return x;
}
is generally regarded as thread safe, because it does this (in pseudo bytecode)
(In the thread's current frame)
push 5
push 5
add integers
return
While this isn't thread safe
int x = 5;
public void unsafe() {
x = 5;
x = x + 5;
return x;
}
because it does this
(in the thread's current frame)
push "this"
push 5
set member x
push "this"
get member x
push 5
add integer
set member x
get member x
return
The latter bytecode makes it apparent that interleaving two threads creates thread-to-thread communications using member x an an intermediary, while the first block of code cannot have any inter-thread communication because there's no intermediary.
Currently it means final
much the same as any local variable, other than it is always "definitely assigned".
In recent JDK7 builds, a Project Coin language change allows it to indicate a degree of implicit static typing is going on. A single catch
can catch a number of different checked exceptions by a common base type, and rethrow with the enclosing context only having catch or declare those exceptions that could (statically speaking) be thrown within the try
. (See the link for a better explanation.)
The final
keyword on variables means that the variable can only be assigned once, and as the assignment here is being done by the compiler it means that the variable cannot be changed later in the code.
This is an important property as it means to the maintainer that this particular variable will have this particular value everywhere it is used and it is not necessary to keep track of where it changes. This is recognized to be so useful that the "Clean up" action in Eclipse allows for adding "final" whereever it possibly can, and I believe that what you see is the result of such an automatic clean up, because most human programmers would keep the catch-block short so such an indication is not needed.