Home  >  Article  >  Java  >  Analysis of the execution order of finally and return in Java (code example)

Analysis of the execution order of finally and return in Java (code example)

不言
不言Original
2018-09-11 14:16:021624browse

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:

Analysis of the execution order of finally and return in Java (code example)

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn