总结
1.try里的"return x;" 会将x保存到局部变量表非x的位置,相当于复制了一份x, 记作xx。若finally里有return语句,则会执行finally里面的return;否则,会将xx(finally里面可以修改x的值,但无法修改xx的值,若xx是引用,比如map,则可以通过x修改了xx里面的内容)拿出来返回。
2.try执行报错,跳到catch,catch的return 和 finally的return 分析如上,优先返回finally的return;
3.当catch里发生了异常,也是会跑到finally代码块的;
4.字节码里finally代码块会多次出现;
具体分析
public static int test3() {
int a = 1;
try {
return a / 0;
} catch (Exception e) {
return a + 2;
} finally {
return a + 3;
}
}
即代码块[2,5]执行报错会跑到catch的开头10,非Exception报错的话跑到finally的开头19。
catch的代码块[10,14]发生异常也会跑到finally开头的19.
可以看到字节码是这样的:
try代码块
finally代码块1 -> try代码无报错,正常退出
// try有Exception报错,跑到catch, 通过finally代码块2退出
catch代码块
finally代码块2
// try有非Exception报错,或catch有异常报错,都是通过finally代码块3退出
finally代码块3
因此上面代码最终返回的是finally里面的值,即a+3 = 4,程序跑起来,执行的结果也是4.
finally {
return a + 3;
}
可以看到是通过finally块复制几次的方式 来保证一定执行finally!!