您的位置:首页 > 编程语言 > Java开发

关于javap编译后多出一部分代码以及finnaly块中加return 无法抛出异常的看法

2016-08-04 18:29 375 查看
先看代码

static int test() throws Exception{
int i = 0;
try {
i = i+2;
return i;
} finally{
i=i+1;
}
}


比较简单,之前知道finally块如果没有返回语句是不影响return的,但是今天突然想从jvm指令的角度去看看为什么,却发现,多出了一行 iinc 0,1的指令,见下图



刚开始有点莫名其妙,后来发现是不是finally块里的东西被优化到前面去了,finally里面又加了一句代码

static int test() throws Exception{
int i = 0;
try {
i = i+2;
return i;
} finally{
i = i + 1;
i = i + 3;
}
}




验证了猜想,可是这是为什么呢,个人理解是jvm做了优化,优化之后可以在不出现异常的情况下,指令不用跳转,finally里面的语句总是要执行的,也可以看到,finally块里面的语句涉及到的i,是通过istore复制过来的,并不会影响return的值。当发生异常时,才进去到编译之后的finally块的代码,这样也能看到最后一条指令是athrow。

下面再看一下在finally里面加上return会出现生么情况。

static int test() throws Exception{
int i = 0;
try {
i = i+2;
return i;
} catch (Exception e) {
// TODO: handle exception
throw e;
}
finally{
i = i + 1;
i = i + 3;

}
}




God,这是什么。之前有人提到在finnaly增加return语句会吃掉抛出的异常问题。多出来的pop语句正好解释了这一点,当异常发生时,进入finnaly后第一条指令就是pop,将栈顶的异常抛出了,最后一条指令也换成了 ireturn。

finally去掉return之后的指令集。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐