The finally keyword in Java is usually used in conjunction with a try catch block. The action to do some resource deallocation before the method ends or when an exception occurs. Recently I've seen some articles on the web that discuss the order of Try Catch finally keyword execution, and give a finally block that was executed at the end of the method.
These views generally suggest that:
1 Finally the keyword is executed before returning to the previous method after the program return statement, where the return value is saved in a temporary area, after the part of the finally block is executed, the value of the staging area is returned.
2 If finally the return value in the block is replaced with the value in the staging area for the replacement in the previous try or catch block in the program.
But is that really the case, and we think carefully that the JVM interprets the bytecode instructions at run time, and when he executes to the return statement, does he know if there is a finally block behind, and if there is no finally block, Whether a byte-code directive or a computer's instruction should be explicit, the JVM is not so intelligent that the same instruction must be clear and contain no two meanings. So when the return statement is running, the unification pops up the contents of the stack and returns to the calling method.
At the same time, we can see another explanation in the book "Deep Java Virtual machines". A JSR instruction is generated when the Java compiler compiles the finally clause, which causes the JVM to switch to the miniature subroutine to execute, which is the finally block, while the return 0 statement in the program is compiled into a back variable in the call to the JSR instruction stack to a local variable, and the JSR instruction is invoked. Execute finally blocks, finally block returns, press the return value in the local variable onto the stack, execute the ireturn instruction, pop the return value from the stack, and return to the calling method, where the return value is saved in the local variable before the JSR instruction is executed. This is the only way to guarantee the consistency of the final program execution, because an exception may occur during the execution of a finally block or a return value. As the deep Java Virtual machine has been written for some years, the implementation and version of the JVM compiler used by the author is also different from the one discussed in this article. So after testing, there is a slight difference in the generation of bytecode for different compiler implementations or versions of the same program. Be interested to see the bytecode generated by the finally clause in this book.
The bytecode generation in this article was generated using Oracle's JDK8U-25 version of compiler compilation.
Let's look at an example below.
1.try Catch Finally Example:
public class Finallytest {public
static void Main (string[] args) {
int r = Test ();
System.out.println (R);
}
public static int test ()
{
try {
System.out.println ("try");
return 1/0;
return 0;
} catch (Exception e) {
System.out.println ("Exception");
return;
} finally{
System.out.println ("finally");}}
The return 0 statement is used in the try block, and the result of the program's operation is:
Try
Finally
0
The return 1/0 statement is used in the try block, and the result of the program running is:
exception
Finally
100
In fact, by running the result we can see that the finally block is executed after the other statements before the return statement in the try or catch block. That is, the order in which the program is written does not match the order in which we execute it, because the JVM interprets the bytecode, so we need to see how the Java compiler compiles the code to see what byte code it generates.
2. Partial bytecode generated by the program: (Java byte Code directive please refer to)
public static int test (); Descriptor: () I flags:acc_public, Acc_static code:stack=2, locals=2, args_size=0 0:getstatic #20
Field Java/lang/system.out:ljava/io/printstream; 3:LDC #36//String try 5:invokevirtual #38//Method Java/io/printstream.println: (ljava/lang/
String;) V 8:getstatic #20//Field Java/lang/system.out:ljava/io/printstream; 11:LDC #41//String finally 13:invokevirtual #38//Method Java/io/printstream.println: (ljava/l ang/string) V 16:iconst_0 17:ireturn 18:astore_0 19:getstatic #20//Field Java/lang/system.
Out:ljava/io/printstream; 22:LDC #43//String exception 24:invokevirtual #38//Method Java/io/printstream.println: (Ljav
a/lang/string) V 27:getstatic #20//Field Java/lang/system.out:ljava/io/printstream; 30:LDC #41//String finally 32:invokevirtual #38 Method Java/io/printstream.println: (ljava/lang/string) V 35:bipush 37:ireturn 38:astore_1
39:getstatic #20//Field Java/lang/system.out:ljava/io/printstream; 42:LDC #41//String finally 44:invokevirtual #38//Method Java/io/printstream.println: (ljava/ lang/string) V 47:aload_1 48:athrow Exception table:from to target type 0 8 Class java/l Ang/exception 0 8
From the red part we can see: 10, line 11 corresponds to the Finally block statement instructions, 16,17 corresponds to the return 0 instruction, after the TRY block other statements, before return. And 19,20 corresponds to the finally block instruction, 21,22 corresponds to the return 100 statement of instructions, after the catch of other statements, return, so we can see what happened behind the Java compiler for us to do all this, As for the exceptions that occur in the program, the JVM finds the address location execution from the exception table that corresponds to handling the exception.
So we can conclude that the statements in the finally block are inserted by the Java compiler before the try block and Catch block return statements, after the other statements. There is also no subroutine to generate a JSR call here. That's why it happens, whether executing a try block or executing a catch block, it eventually executes the finally block before the method returns.
The above Java finally block execution time comprehensive analysis is small to share all the content, hope to give you a reference, also hope that we support cloud habitat community.