看了一位博友的一篇文章,讲解的是关于java中关于try、catch、finally中一些问题
下面看一个例子(例1),来讲解java里面中try、catch、finally的处理流程
public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
try {
t = "try";
return t;
} catch (Exception e) {
// result = "catch";
t = "catch";
return t;
} finally {
t = "finally";
}
}
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
}
}
首先程序执行try语句块,把变量t赋值为try,由于没有发现异常,接下来执行finally语句块,把变量t赋值为finally,然后return t,则t的值是finally,最后t的值就是finally,程序结果应该显示finally,但是实际结果为try。为什么会这样,我们不妨先看看这段代码编译出来的class对应的字节码,看虚拟机内部是如何执行的。
我们用javap -verbose TryCatchFinally 来显示目标文件(.class文件)字节码信息
-
系统运行环境:mac os lion系统 64bit
-
jdk信息:Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-11M3527) Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02-402, mixed mode)
编译出来的字节码部分信息,我们只看test方法,其他的先忽略掉
public static final java.lang.String test();
Code:
Stack=1, Locals=4, Args_size=0
0: ldc #16; //String
2: astore_0
3: ldc #18; //String try
5: astore_0
6: aload_0
7: astore_3
8: ldc #20; //String finally
10: astore_0
11: aload_3
12: areturn
13: astore_1
14: ldc #22; //String catch
16: astore_0
17: aload_0
18: astore_3
19: ldc #20; //String finally
21: astore_0
22: aload_3
23: areturn
24: astore_2
25: ldc #20; //String finally
27: astore_0
28: aload_2
29: athrow
Exception table:
from to target type
8 13 Class java/lang/Exception
8 24 any
19 24 any
LineNumberTable:
line 5: 0
line 8: 3
line 9: 6
line 15: 8
line 9: 11
line 10: 13
line 12: 14
line 13: 17
line 15: 19
line 13: 22
line 14: 24
line 15: 25
line 16: 28
LocalVariableTable:
Start Length Slot Name Signature
27 0 t Ljava/lang/String;
10 1 e Ljava/lang/Exception;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_fra