测试类的原型是这样子的

  1. public class TryCatchFinallyToReturn {
  2.  
  3. public static void main(String[] args) {
  4. System.out.println(test());
  5. }
  6.  
  7. public static int test() {
  8. try {
  9. System.out.println("try block.");
  10. throwMethod();
  11. return 1;
  12. } catch(Exception e) {
  13. System.out.println("catch block.");
  14. return 2;
  15. } finally {
  16. System.out.println("finally");
  17. return 3;
  18. }
  19. }
  20.  
  21. public static void throwMethod() throws Exception {
  22.  
  23. }
  24.  
  25. }

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

finally block does not complete normally

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

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

  1. try block.
  2. finally block.
  3. 3

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

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

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

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

运行一下(结果2)

  1. try block.
  2. throw.
  3. catch block.
  4. finally block.
  5. 3

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

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

最后删除finally{} 中的return 3

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

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

  1. try block.
  2. finally block.
  3. 1
  1. try block.
  2. throw.
  3. catch block.
  4. finally block.
  5. 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}再也没有机会返回了。

Try-Catch-Finally代码块中的return的更多相关文章

  1. try catch finally语句块中存在return语句时的执行情况剖析

    2种场景 (1) try中有return,finally中没有return(注意会改变返回值的情形);(2) try中有return,finally中有return; 场景代码分析(idea亲测) 场 ...

  2. 当try-catch-finally代码块遇上return,代码执行流程是怎样

    这里打算用一个Java读取文件内容的例子来测试,文件存在,不抛异常,文件不存在,则抛出FileNotFoundException: Java读取文件代码如下: /** * 根据路径和文件名获取内容 * ...

  3. [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?

    在 Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity. 所有对象的非同步 方法都能够在任意时刻被任意线 ...

  4. java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?

    在Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity.所有对象的非同步方法都能够在任意时刻被任意线程调用 ...

  5. 孤荷凌寒自学python第三十二天python的代码块中的异常的捕获

    孤荷凌寒自学python第三十二天python的代码块中的异常的捕获 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天简单了解了Python的错误陷阱,了解到其与过去学过的其它语言非常类似 ...

  6. try、catch、finally--try块里有return,finally还执行吗?

    finally块的作用是,保证无论出现什么情况,finally块里的代码一定会被执行. 由于程序执行return就意味着结束对当前函数的调用并跳出这个函数体,所以任何语句要执行都只能在return之前 ...

  7. .NET中如何在同步代码块中调用异步方法

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月2日. 在同步代码块中调用异步方法,方法有很多. 一.对于有返回值的Task 在同步代码块中直接访问 Task 的 Result ...

  8. 在MVC视图的代码块中,直接输出文本,有几种方式?

    @{ <div>我爱IT,我是程序员,我骄傲---</div> <!--在C#代码块中,输出文本--> <!--1.0 使用Razor内置标签text--&g ...

  9. java 为什么wait(),notify(),notifyAll()必须在同步(Synchronized)方法/代码块中调用?

    wait()作用:该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止.条件:在调用wait()之前,线程必须要获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法.进入wai ...

随机推荐

  1. Java数据结构Vetor

    Java数据结构Vector /** * <html> * <body> * <P> Copyright JasonInternational</p> ...

  2. ASP.NET WEB应用程序(.network4.5)MVC 工作原理

    MVC就是模型.视图.控制器. 项目中控制器对应Controllers目录,视图对应Views目录,模型对应Models目录. 1.当我们创建一个控制器时,比如在Controllers目录新建一个名字 ...

  3. sql 视图的好处

    第一点:使用视图,可以定制用户数据,聚焦特定的数据. 解释: 在实际过程中,公司有不同角色的工作人员,我们以销售公司为例的话,采购人员,可以需要一些与其有关的数据,而与他无关的数据,对他没有任何意义, ...

  4. Python练习_装饰器、生成器_day12

    装饰器 装饰器篇: 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码. def login(func): def inner( ...

  5. 解决window 12 service 不能调用excel ,报"System.Runtime.InteropServices.COMException (0x800A03EC)

    Step1: 运行comexp.msc -32 注意因为excel 是32 位的,所以这里用的32位的操作, 如用64位的操作命令:dcomcnfg.exe,将找不到excel com 进入compo ...

  6. 【转载】salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句

    salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句 salesforce如果简单的说可以大概分成两个部分:Apex,VisualForce Page. 其中Apex ...

  7. 第五章、drf-JWT认证

    目录 JWT认证 JWT认证方式与其他认证方式对比: 优点 格式 drf - jwt 插件 官网 安装 token的签发与校验初识: 签发token 校验token 自定义drf-jwt配置 sett ...

  8. 常用git指令记录

    Generating an SSH key Checking for existing SSH keys Generating a new SSH key and adding it to the s ...

  9. 14_sqoop数据导入

    3.Sqoop的数据导入 “导入工具”导入单个表从RDBMS到HDFS.表中的每一行被视为HDFS的记录.所有记录都存储为文本文件的文 本数据(或者Avro.sequence文件等二进制数据) 3.1 ...

  10. linux实操_shell

    简单shell编写: 执行方式: (1)推荐 (2)不推荐