try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?
1.只要 try 语句块有被执行到,那么 finally 语句块一定会被执行。
2.try 语句块 或 catch 语句块中,如果 return 的是一个语句(比如:return "success"),那么 finally 语句块会在 return 语句之前执行;如果 return 的是一个方法(比如:return add(),add() 是类中的方法),那么 finally 语句块会在方法返回之前执行。
3.如果 finally 语句块里有 return 语句,那么此方法直接返回。即,try 语句块 或 catch 语句块中有 return 语句,return 语句将不会执行。
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 ]
}
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。