public class TestTryCatch {
public static void main(String[] args) {
TestTryCatch test = new TestTryCatch();
System.out.println(test.fun());
System.out.println(test.fun2());
}
public int fun() {
int i = 10;
try {
return i;
} finally {
i = 20;
}
}
public StringBuilder fun2() {
StringBuilder s = new StringBuilder("Hello");
try {
//doing something
s.append("Word");
return s;
} catch (Exception e) {
return s;
} finally {
s.append("finally");
}
}
}
javap -c TestTryCatch.class 之后,就可以看见了
Compiled from "TestTryCatch.java"
public class cn.com.flamezealot.base.jvm.trycatch.TestTryCatch {
public cn.com.flamezealot.base.jvm.trycatch.TestTryCatch();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #1 // class cn/com/flamezealot/base/jvm/trycatch/TestTryCatch
3: dup
4: invokespecial #16 // Method "<init>":()V
7: astore_1
8: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;
11: aload_1
12: invokevirtual #23 // Method fun:()I
15: invokevirtual #27 // Method java/io/PrintStream.println:(I)V
18: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;
21: aload_1
22: invokevirtual #33 // Method fun2:()Ljava/lang/StringBuilder;
25: invokevirtual #37 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
28: return
public int fun();
Code:
0: bipush 10 10入栈顶
2: istore_1 栈顶数据保存到局部变量数组第2个位置
3: iload_1 取出第2个局部变量入栈顶
4: istore 4 栈顶数据保存到第5个局部变量
6: bipush 20 20入栈顶
8: istore_1 栈顶数据保存到第2个局部变量
9: iload 4 第5个局部变量入栈顶
11: ireturn 返回
12: astore_2 栈顶数据放到局部变量数组第3个位置
13: iload_1 第2个局部变量的值放入栈顶
14: istore 4 栈顶数据保存到第5个局部变量
16: bipush 20 20入栈顶
18: istore_1 保存到第2个局部变量
19: iload 4 第5个局部变量值入栈顶
21: ireturn 返回
22: astore_3 栈顶数据放到局部变量数组第4个位置
23: bipush 20 20入栈顶
25: istore_1 保存到第2个局部变量
26: aload_3 局部变量数组第4个位置数据入栈顶
27: athrow 将栈顶的数值作为异常或错误抛出
Exception table:
from to target type
3 6 12 Class java/lang/Exception
3 6 22 any
12 16 22 any
public java.lang.StringBuilder fun2();
Code:
0: new #52 // class java/lang/StringBuilder
3: dup 复制一份对象引用,因为接下来要先初始化,再保存到变量,所以这里复制了一份
4: ldc #54 // String Hello
6: invokespecial #56 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 类初始化会弹出一个引用
9: astore_1 另一个引用存入局部变量表2号位置
10: aload_1
11: ldc #59 // String Word
13: invokevirtual #61 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: pop 这里返回值没有赋给任何变量,所以pop出栈
17: aload_1
18: astore 4
20: aload_1
21: ldc #65 // String finally
23: invokevirtual #61 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
26: pop
27: aload 4 sotre、load的都是引用
29: areturn
30: astore_2
31: aload_1
32: astore 4
34: aload_1
35: ldc #65 // String finally
37: invokevirtual #61 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
40: pop
41: aload 4
43: areturn 每次return前都会执行fianlly里的方法
44: astore_3
45: aload_1
46: ldc #65 // String finally
48: invokevirtual #61 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
51: pop
52: aload_3
53: athrow 异常处理前也会执行finally里的方法
Exception table:
from to target type
10 20 30 Class java/lang/Exception
10 20 44 any
30 34 44 any
}
jvm的指令集说明可以看这里