创建一个简单的例子
public class TryCatch {
public static void main(String[] args) {
int num = 0;
try {
num = 11;
return;
} catch (Exception e) {
num = 22;
return;
}
finally {
num = 33;
return;
}
}
}
当finally块中有return时
//使用该指令查看编译后的字节码
javap -c TryCatch
public class org.TryCatch.TryCatch {
public org.TryCatch.TryCatch();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
//try块
0: iconst_0
1: istore_1
2: bipush 11
4: istore_1
//如果finally块中有return,则使用goto跳转到finally块
5: goto 16
//catch块
8: astore_2
9: bipush 22
11: istore_1
//如果finally块中有return,则使用goto跳转到finally块
12: goto 16
15: pop
//finally块
16: bipush 33
18: istore_1
//最后在这里返回
19: return
Exception table:
from to target type
2 8 8 Class java/lang/Exception
2 15 15 any
}
当finally块中不存在return时
public class org.TryCatch.TryCatch {
public org.TryCatch.TryCatch();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
//try块
0: iconst_0
1: istore_1
2: bipush 11
4: istore_1
//复制一份finally块中的代码
5: bipush 33
7: istore_1
//try最后返回
8: return
//catch块
9: astore_2
10: bipush 22
//复制一份finally块中的代码
12: istore_1
13: bipush 33
15: istore_1
//catch最后返回
16: return
//finally块
17: astore_3
18: bipush 33
20: istore_1
21: aload_3
22: athrow
Exception table:
from to target type
2 5 9 Class java/lang/Exception
2 5 17 any
9 13 17 any
}
1 . 从以上两段字节码可以看出,当finally和try中都存在return语句时,try中指令执行完后会跳转到finally,执行finally块中的指令,最后执行finally块中的return指令,注意这里不会再跳转到try中执行try块中的return指令.
2 . 当只有try中存在return语句时,try会复制一份finally中的指令到try中执行。
3 . catch和try的处理相同。
三个语句块中都不存在return时
public static void main(java.lang.String[]);
Code:
//try
0: iconst_0
1: istore_1
2: bipush 11
4: istore_1
5: goto 24
//catch
8: astore_2
9: bipush 22
//复制finally中的语句
11: istore_1
12: bipush 33
14: istore_1
15: goto 27
//finally
18: astore_3
19: bipush 33
21: istore_1
22: aload_3
23: athrow
//为什么多这个??
24: bipush 33
26: istore_1
//自动添加return
27: return
三个语句块中都不存在return时
1. try中执行完会跳转去执行finally的指令 ,再执行try-catch-finally之后的指令,最后执行return指令结束方法。
2. 如果出现异常,catch中会复制一份finally的指令,执行完后跳转到27: return结束方法。