开发者社区> 问答> 正文

[@饭娱咖啡][¥20]try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?

try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?

展开
收起
红尘de无道 2018-10-30 19:00:42 4084 0
2 条回答
写回答
取消 提交回答
  • 主要从事 Java 后端开发。

    1.只要 try 语句块有被执行到,那么 finally 语句块一定会被执行。
    2.try 语句块 或 catch 语句块中,如果 return 的是一个语句(比如:return "success"),那么 finally 语句块会在 return 语句之前执行;如果 return 的是一个方法(比如:return add(),add() 是类中的方法),那么 finally 语句块会在方法返回之前执行。
    3.如果 finally 语句块里有 return 语句,那么此方法直接返回。即,try 语句块 或 catch 语句块中有 return 语句,return 语句将不会执行。

    2019-07-17 23:11:24
    赞同 展开评论 打赏
  • 追求性能极限的人

    答案

    finally{}的code会被执行,会在RETURN之前执行;

    解析

    • 原代码

      public class Test {
      
         public static void main(String... args) {
            try {
               System.out.println("FROM:BEFORE");
               return;
            } finally {
               System.out.println("FROM:FINALLY");
            }
         }
      }
    • 编译后运行

      FROM:BEFORE
      FROM:FINALLY
    • 原因

    为了更好的解析运行后的结果,以及挣这20块钱,我们深入解答下:JVM中是怎么执行TRY...CATCH语句的。

    16:return是我们真正即将要return的地方,注意看11~13行和21~23行,javac在编译的时候会将finally语句块的代码copy到return之前,所以finaly的code一定会在return之前执行

    如果TRY...CATCH块中有多个return,那么每个return前边都会被copy了finally块的代码。

    这里也不一定是绝对,不同版本的JVM有不同的优化策略,这里只是从更底层来证明:FINALLY一定会被运行,而且是在RETURN之前

    public static void main(java.lang.String...);
      descriptor: ([Ljava/lang/String;)V
      flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
      Code:
        stack=2, locals=2, args_size=1
           0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
           3: ldc           #3                  // String FROM:BEFORE
           5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
           8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
          11: ldc           #5                  // String FROM:FINALLY
          13: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          16: return
          17: astore_1
          18: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
          21: ldc           #5                  // String FROM:FINALLY
          23: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          26: aload_1
          27: athrow
        Exception table:
           from    to  target type
               0     8    17   any
        LineNumberTable:
          line 5: 0
          line 8: 8
          line 6: 16
          line 8: 17
        StackMapTable: number_of_entries = 1
          frame_type = 81 /* same_locals_1_stack_item */
            stack = [ class java/lang/Throwable ]
    }
    
    2019-07-17 23:11:24
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载