1、代码
public class Test {
public String hello() {
String str = "hello";
try {
return str;
} finally {
str = "world";
}
}
}
2、解释
我们直接来看字节码,如下所示:
0 ldc #2 <hello>
2 astore_1
3 aload_1
4 astore_2
5 ldc #3 <world>
7 astore_1
8 aload_2
9 areturn
10 astore_3
11 ldc #3 <world>
13 astore_1
14 aload_3
15 athrow
ldc #2 <hello>
代表将字符串hello
压入操作数栈中,astore_1
代表将字符串hello
弹出操作数栈并且放在局部变量表中下标为1
的位置(下标为0
的位置放置的是this
),aload_1
代表将字符串hello
从局部变量表中下标为1
的位置取出来在压入操作数栈中,astore_2
代表将字符串hello
弹出操作数栈并且放在局部变量表中下标为2
的位置,ldc #3 <world>
代表将字符串world
压入操作数栈,astore_1
代表将字符串world
弹出操作数栈并且放在局部变量表中下标为1
的位置,此时 局部变量表中下标为0的位置放的是this,下标为1的位置放的是字符串world,下标为2的位置放的是字符串hello
,然后继续往下看字节码,aload_2
代表将字符串hello
从局部变量表中下标为2
的位置取出并压入到操作数栈,areturn
表示将字符串hello
返回,而第10行至15行的内容是处理异常的部分,其实问题已经解释清楚了,如果有兴趣在了解剩余字节码指令的往下看
先来看一下异常表,如下所示:
当字节码文件中的第3行
到第5行
中间出现异常信息,将会立即执行finally
中的代码并抛出异常,不过这个不是重点
总之,finally中的代码一定会执行,它的执行顺序是在return之前,无论是try或者catch中的return,比如i=0,然后catch中是return ++i,而finally中是++i,那么当计算了return后面的++i之后就会把这个1存起来,等待返回这个值,此时i其实等于1,而finally中的++i开始执行,然后i就是2了,这也是该方法中i的最终值,现在return将存起来那个1返回就可以了