public class Test {
public static void main(String[] args) {
System.out.println(ddd());
}
public static int ddd(){
int m=0;
try{
return m++;
}finally{
System.out.println(m);
}
}
}
这个打印的结果是:
1
0
//-----------------------原因分析-------------------------
执行流程如下:
1)执行return返回语句(return之后的语句内容),计算返回值,暂存在一个临时变量中。
2)执行finally语句块。
3)return 原来已经计算得到的结果值。
为了让上面分析更具说服力,下面我们观察一下编译之后的class字节码。
javac Test.java //编译java文件
javap -c Test //查看class字节码(java虚拟机指令)
public class Test extends java.lang.Object{
public Test();
Co
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Co
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: invokestatic #3; //Method ddd:()I
6: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
9: return
public static int ddd();
Co
0: iconst_0 //声明常量
1: istore_0 //将常量赋值给0号变量(此处为m)
2: iload_0 //装载0号变量的值(读取m的值)
3: iinc 0, 1 //做自增运算(0是上一步读取的m的值,自增就是在原来的数值上面加1)
6: istore_1 //把结果存放到1号变量空间里(临时存放返回表达式计算结果,此处自增运算返回结果为0
7: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_0
11: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
14: iload_1 //加载临时存储的计算结果1号变量中的值
15: ireturn //返回执行
16: astore_2
17: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
20: iload_0
21: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
24: aload_2
25: athrow
Exception table:
from to target type
2 7 16 any
16 17 16 any
}
蓝色注释为我对Test.class文件的理解。从中可以看出上述的执行流程。为了更好的练习我们的理解是否正确,有下面一道例子,希望自己做一下加深理解。
public static int getResult() { | public static int getResult() {
int result = 0; | int result = 0;
try { | try {
result = 1; | result = 1;
return result; | return result;
} catch (Exception e) { | } catch (Exception e) {
result = 2; | result = 2;
} finally { | } finally {
result = 3; | result = 3;
} | return result;
return result; | }
} | }
返回结果分别为 1, 3