I have read an article aboutReturnAndFinallyThe article on execution sequence is analyzed only at the Java language level. In fact, I think it's easy to seeBytecodeIt may be clearer.
Recently, I have been looking at Java Virtual Machine specifications and found that direct analysis of bytecode can help me better understand the Java language.
First, there is only oneTry-finally, NoCatch.
Try-finally
public class ExceptionTest { public void tryFinally() { try { tryItOut(); } finally { wrapItUp(); } } // auxiliary methods public void tryItOut() { } public void wrapItUp() {}}
Passjavap -c ExceptionTest
To view its bytecode.
public void tryFinally(); Code: 0: aload_0 1: invokevirtual #2 // Method tryItOut:()V 4: aload_0 5: invokevirtual #3 // Method wrapItUp:()V 8: goto 18 11: astore_1 12: aload_0 13: invokevirtual #3 // Method wrapItUp:()V 16: aload_1 17: athrow 18: return Exception table: from to target type 0 4 11 any
If no exception is thrown, the execution sequence is
0: aload_01: invokevirtual #2 // Method tryItOut:()V4: aload_05: invokevirtual #3 // Method wrapItUp:()V18: return
If an exception is thrown, the JVM will
Exception table: from to target type 0 4 11 any
. If the command is between 0 and 4 bytes, it throws any type (Any Type) Will jump to 11 bytes to continue running.
11: astore_112: aload_013: invokevirtual #316: aload_117: athrow
Astore_1Saves the thrown exception objectLocal variableThe second element of the array. The following two lines of commands are used to call the member method.wrapItUp
.
12: aload_013: invokevirtual #3
Finally
16: aload_117: athrow
Throw an exception again.
Through the above analysis, we can draw a conclusion
In try-Finally, the exception thrown by the try block is saved in local variable first, and then the Finally block is executed. After the execution is complete, the exception is thrown again.
If we modify the code, return directly in the try block.
Try-return-finally
public void tryFinally() { try { tryItOut(); return; } finally { wrapItUp(); }}
"Disassembly:
0: aload_0 1: invokevirtual #2 // Method tryItOut:()V 4: aload_0 5: invokevirtual #3 // Method wrapItUp:()V 8: return 9: astore_110: aload_011: invokevirtual #3 // Method wrapItUp:()V14: aload_115: athrow
It can be seen that the Finally block code is still put before return.
If the try block containsreturn statement
The finally code must be executed first and then returned.
This is the JVM specification.
Compilation ofTry-finallyStatement is similar to thatTry-catch. Pior to transferring control outsideTryStatement, whether that transfer is normal or abrupt, because an exception has been thrown,FinallyClause must first be execute.
Try-catch-finally
Add a catch block to the above Code
public void tryCatchFinally() { try { tryItOut(); } catch (TestExc e) { handleExc(e); } finally { wrapItUp(); }}
Javap
public void tryCatchFinally(); Code: 0: aload_0 1: invokevirtual #2 4: aload_0 5: invokevirtual #3 8: goto 31 11: astore_1 12: aload_0 13: aload_1 14: invokevirtual #5 17: aload_0 18: invokevirtual #3 21: goto 31 24: astore_2 25: aload_0 26: invokevirtual #3 29: aload_2 30: athrow 31: returnException table: from to target type 0 4 11 Class TestExc 0 4 24 any 11 17 24 any
PassException tableWe can see that:
- Catch listening 0 ~ The 4-byte type is
TextExc
.
- Finally is 0 ~ 4 and 11 ~ 17 bytes exception of any type.
That is to sayCatch BlockIt is also inFinally blockWithin the jurisdiction. IfCatch BlockInReturn Statement, So it must be inFinally blockThen run.
View Original article http://www.liangfeizc.com/blog/article/32/
Use bytecode to see try-catch-finally and return