As widely known the finally clause of Java has be implemented as a mini-subroutine. The subrountine is within the bytecodes of the method containing the finally clause.
The jsr instruction cause a local jump to the sub-routine code and ret instruction cause a return from the sub-routine.
A very interesting impact of this implementation can be seen below.
public int getNum()
{
int i=2;
try
{
return i;
}
finally
{
i=3;
}
}
The return value of the above method is always 2 not 3. The value change in the finally clause doesn't impact the return value.
The reason behind such a behaviour is as follows.
The finally clause is executed prior to the return statement as expected. Before jumping to the code in finally clause, the return value is popped off from the stack and stored in a local variable. The reason for this action is that in Java finally clause can to also place another return value on the stack, can be through a return statement in finally itself.
So the value of i which is 2 is popped-off the stack and stored in a local variable. During the execution of the finally clause the value of i is altered to 3. The finally clause finishes execution and the control is transferred back to the return statement.
~*~Now the return statement uses the stored value as the return value of the method. The return statement is not evaluated again, implies i is not evaluated again, so the change made to i in the finally clause is ineffective.~*~
The change can be made effective only by explicitly adding a return statement to return the value of i in the finally clause.
The reason behind such a behaviour is as follows.
The finally clause is executed prior to the return statement as expected. Before jumping to the code in finally clause, the return value is popped off from the stack and stored in a local variable. The reason for this action is that in Java finally clause can to also place another return value on the stack, can be through a return statement in finally itself.
So the value of i which is 2 is popped-off the stack and stored in a local variable. During the execution of the finally clause the value of i is altered to 3. The finally clause finishes execution and the control is transferred back to the return statement.
~*~Now the return statement uses the stored value as the return value of the method. The return statement is not evaluated again, implies i is not evaluated again, so the change made to i in the finally clause is ineffective.~*~
The change can be made effective only by explicitly adding a return statement to return the value of i in the finally clause.