测试类的原型是这样子的

public class TryCatchFinallyToReturn {

    public static void main(String[] args) {
System.out.println(test());
} public static int test() {
try {
System.out.println("try block.");
throwMethod();
return 1;
} catch(Exception e) {
System.out.println("catch block.");
return 2;
} finally {
System.out.println("finally");
return 3;
}
} public static void throwMethod() throws Exception { } }

可以看到finally代码块整个大括号都出现了警告了,

finally block does not complete normally

说明finally{}中出现return是不合适的。

强行运行一下,结果是这样的(结果1)

try block.
finally block.
3

通过断点追踪,try{}中的return 1已经运行到了,但是try{}正常运行结束后,finally{}必须要被执行

最后所以真正的返回值是3

变更一下测试原型,测试一下出现异常的情况

    public static void throwMethod() throws Exception {
System.out.println("throw.");
throw new Exception();
}

运行一下(结果2)

try block.
throw.
catch block.
finally block.
3

异常被捕获到了catch{}中的return 2确保了运行,但是返回值依然是finall{}中的return 3。

同样的,通过断点追踪发现return 2也被运行到了,但是被return 3覆盖

最后删除finally{} 中的return 3

        } finally {
System.out.println("finally block.");
}

运行一下通过调整throwMethod方法,分别测试一下正常情况和异常情况(结果3)(结果4)

try block.
finally block.
1
try block.
throw.
catch block.
finally block.
2

返回值正确了。

现在可以得到4个结论

A、运行时发生异常的那条语句再也没有机会运行到了,原因是异常被catch()捕获到,程序流程进入了catch{}

这点可以通过结果2看到,断点没有运行到return 1

B、无论try{}还是catch{}发生了什么,finally{}中的语句一定会运行到

这点可以通过结果1234看到,"finally block."怎么样都是打印出来的

C、当try{}或是catch{}发生return时,方法并不是立即返回的,而是等finally{}执行完毕后,才返回

这点可以通过结果34看到,在打印结果"1"或"2"的前一行,"finally block."被打印出来了

D、如果设计不当,使finally{}中存在return语句,那么执行当finally{return}时,方法会直接返回,finally{}执行之前预定需要返回的返回值,会被覆盖掉

这点可以通过结果12看到,返回值都是finally里的3而不是try里的1或catch里的2。

C、D可以如此理解,没有返回语句的finally{}比较本分,try{}、catch{}顾及到语言限定,在返回前给了finally{}运行的机会,finally运行完毕后返回正确的值;

但编码使另finally{}中出现返回语句,那么finally{}就像是一个过河拆桥的人,利用try{}或是catch{}给的机会,执行了自己的返回语句,让方法直接结束,try{return}或catch{return}再也没有机会返回了。

最新文章

  1. Linux下多线程下载利器 axel
  2. SELinux关闭和开启
  3. Grunt 新手指南
  4. html5新增选择器
  5. 进入git diff 界面,无法继续输入命令
  6. require.js js模块化方案
  7. JSP相对路径与绝对路径探秘
  8. MySql中的变量定义(转)
  9. Spring学习之Ioc控制反转(2)
  10. Android Sqlite数据库执行插入查询更新删除的操作对比
  11. 安装mcrouter
  12. NandFlash学习
  13. Spring Boot使用Druid连接池基本配置
  14. 苹果手机不兼容autoplay属性
  15. Yuan先生的博客网址
  16. Android EventBus3.x 使用详解
  17. 关于ubuntu软件卸载的问题
  18. CF576E Painting Edges
  19. VBA 自动得到分数
  20. delphi如何检索adoquery里面某一列存在的重复行?

热门文章

  1. JAVA的转义字符
  2. Vue绑定的table页面在Chrome浏览器左右抖动
  3. Aop动态代理和cglib
  4. Java字节码方法表与属性表深度剖析
  5. bitset 来计算位
  6. dubbo的初探
  7. java基础:多态过程中的动态绑定
  8. (四)AppScan用外部设备(ios,安卓)录制app脚本进行安全测试
  9. Lua 学习之基础篇三<Lua 字符串操作>
  10. MongoDB常用语句大全