The content of this article is about the execution sequence analysis (code examples) of finally and return in Java. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
We all know the execution characteristics of finally
1. No matter whether there is an exception or not, the code in the finally block will be executed;
2. When there is return in try and catch , finally will still be executed.
Then the question is, what is the execution order?
A simple test class and decompiled bytecode:
public class Test { publicstatic void main(String[] args) { System.out.println(test()); } publicstatic int test() { try{ System.out.println("Codesin try block."); return0; }catch (Exception e) { System.out.println("Codesin catch block."); return100; }finally { System.err.println("Codesin finally block."); } } } /* public static int test(); Code: 0: getstatic #2 // Fieldjava/lang/System.out:Ljava/io/PrintStream; 3: ldc #5 // String Codes in try block. 5: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: iconst_0 9: istore_0 10: getstatic #7 // Field java/lang/System.err:Ljava/io/PrintStream; 13: ldc #8 // String Codes in finallyblock. 15: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 18: iload_0 19: ireturn 20: astore_0 21: getstatic #2 // Fieldjava/lang/System.out:Ljava/io/PrintStream; 24: ldc #10 // String Codes in catchblock. 26: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 29: bipush 100 31: istore_1 32: getstatic #7 // Fieldjava/lang/System.err:Ljava/io/PrintStream; 35: ldc #8 // String Codes in finallyblock. 37: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 40: iload_1 41: ireturn 42: astore_2 43: getstatic #7 // Fieldjava/lang/System.err:Ljava/io/PrintStream; 46: ldc #8 // String Codes in finallyblock. 48: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 51: aload_2 52: athrow */
You can compare the code we wrote with the compiled bytecode:
I found that the virtual machine has done a lot of things for us. It inserted the finally statement block between the try, catch and return statements. This is why finally will be executed regardless of whether there is an exception or not, whether it returns or not. Since, finally will be executed, then whatever is returned in finally is what is returned. Since all returns before finally are invalid, what is the meaning of return? Therefore, in practice, finally blocks are not allowed to return. The eclipse compiler will prompt warning: finallyblock does not complete normally.
Test code for several situations
try{ return; }catch(){} finally{} return;
Test code:
1.Basic data type
public static int test1(){ int a = 10; try{ a = 20; return a; }catch(Exception e){ //other codes. }finally{ a += 5; //other codes. } return a; }//最终返回值为20
2.Reference data type changes the value of the reference object
public static StringBuffer test2(){ StringBuffer sb = new StringBuffer("abc"); try{ return sb; }catch(Exception e){ //other codes. }finally{ sb.append("DEF"); //other codes. } return sb; }//最终返回中内容为abcDEF
public static StringBuffer test3(){ StringBuffer sb = new StringBuffer("abc"); try{ return sb; }catch(Exception e){ //other codes. }finally{ sb = new StringBuffer("DEF"); //other codes. } return sb; }//最终返回值中的内容为abc
In the test of this situation, it can be found that if there is a return statement before finally , finally, no matter what modifications are made to the return variable, the variable itself will not change. For example, reassigning a value to a basic type variable or reassigning a reference to a reference type variable will not be recorded in the return value. However, the statement in finally will be executed, so the content of the object pointed to by the reference type variable in finally can be modified, and the modification is effective. This situation can be understood this way. When encountering a return statement, the virtual machine builds a house for the return value. Can the house be demolished at will? cannot. But the people in the house can change. The variables of basic data types and reference types themselves are houses, and the contents of the objects pointed to by reference type variables are the people in the house.
There is such a small test:
public static int test(int num){ int a = 10; try{ return a; }catch(ArithmeticException e){ a = 20; return a; }finally{ a = 30; return a; } }
1.1 What is the return value when there is no exception in the try block?
1.2 What is the return value when there is an ArithmeticException in the try block?
1.3 What is the return value when there are other exceptions in the try block?
Answer: All are 30. The reason is that after executing the code before the return in the try block, the jvm inserts the code in the finally block between the returns. The finally block contains return, so it returns directly. .
Related recommendations:
The execution order of try, finally and return statements in Java
Examples of code blocks in Java Execution order
The above is the detailed content of Analysis of the execution order of finally and return in Java (code example). For more information, please follow other related articles on the PHP Chinese website!