Try-Catch-Finally代码块中的return
测试类的原型是这样子的
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}再也没有机会返回了。
Try-Catch-Finally代码块中的return的更多相关文章
- try catch finally语句块中存在return语句时的执行情况剖析
2种场景 (1) try中有return,finally中没有return(注意会改变返回值的情形);(2) try中有return,finally中有return; 场景代码分析(idea亲测) 场 ...
- 当try-catch-finally代码块遇上return,代码执行流程是怎样
这里打算用一个Java读取文件内容的例子来测试,文件存在,不抛异常,文件不存在,则抛出FileNotFoundException: Java读取文件代码如下: /** * 根据路径和文件名获取内容 * ...
- [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
在 Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity. 所有对象的非同步 方法都能够在任意时刻被任意线 ...
- java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
在Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity.所有对象的非同步方法都能够在任意时刻被任意线程调用 ...
- 孤荷凌寒自学python第三十二天python的代码块中的异常的捕获
孤荷凌寒自学python第三十二天python的代码块中的异常的捕获 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天简单了解了Python的错误陷阱,了解到其与过去学过的其它语言非常类似 ...
- try、catch、finally--try块里有return,finally还执行吗?
finally块的作用是,保证无论出现什么情况,finally块里的代码一定会被执行. 由于程序执行return就意味着结束对当前函数的调用并跳出这个函数体,所以任何语句要执行都只能在return之前 ...
- .NET中如何在同步代码块中调用异步方法
更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月2日. 在同步代码块中调用异步方法,方法有很多. 一.对于有返回值的Task 在同步代码块中直接访问 Task 的 Result ...
- 在MVC视图的代码块中,直接输出文本,有几种方式?
@{ <div>我爱IT,我是程序员,我骄傲---</div> <!--在C#代码块中,输出文本--> <!--1.0 使用Razor内置标签text--&g ...
- java 为什么wait(),notify(),notifyAll()必须在同步(Synchronized)方法/代码块中调用?
wait()作用:该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止.条件:在调用wait()之前,线程必须要获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法.进入wai ...
随机推荐
- (十四)Hibernate中的多表操作(4):单向一对一
案例一: 注解方式实现一对一 UserBean.java package bean; import java.io.Serializable; import javax.persistence.Col ...
- C#通过地址获取省市区(基于百度地图API)
最近公司有个需求,想通过地址获取对应的省市区,本来想直接通过对地址的截取,对于完整的地址还可以,不完整的就没法用了 所以本篇通过百度地图API来获取地址 第一步:申请ak密钥 登录百度地图开放平台,按 ...
- CPU的基本组成
1.CPU是用来运算的(加法运算.乘法运算.逻辑运算(与.或.非)等) 2.运算操作涉及到数据输入(input).处理.数据输出(output).A和B是输入数据,加法运算时处理.C是输出数据. 3. ...
- 3.通道 Channel
一.通道(Channel):由java.nio.channels包定义的 .Channel 表示 IO 源与目标打开的连接. Channel 类似于传统的 ‘流’.只不过 Channel 本身不能直接 ...
- Redis 学习-Redis Sentinel
一.启动服务 1. 配置文件 sentinel.conf daemonize yes # 是否守护进程启动 pidfile "/var/run/redis-sentinel-26379.pi ...
- Python asyncio 模块
Python 3.4 asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持. asyncio的编程模型就是一个消息循环.我们从asyncio模块中直接获取一个EventLo ...
- 2.Vue调试工具vue-devtools的安装步骤和使用
1.安装步骤: 打开谷歌浏览器设置 -->扩展程序 -->勾选开发者模式 --->加载已解压的扩展程序 --->选择“chrome扩展”文件夹即可:
- Nginx系列1.1:ubuntu16.04编译nginx-rtmp流媒体服务器
1.下载nginx和nginx-rtmp-module nginx官网:nginx.org tar.gz文件 解压缩命令: wget https://nginx.org/download/nginx- ...
- PAT Advanced 1073 Scientific Notation (20 分)
Scientific notation is the way that scientists easily handle very large numbers or very small number ...
- java线程基础巩固---线程间通信快速入门,使用wait和notify进行线程间的数据通信
之前已经对于线程同步相关的知识点进行了详细的学习,这次来学习一下线程间的通信相关的知识,话不多说直接用代码进行演练,以一个简陋的生产者消费者模型来初步了解下线程间通信是怎么一回事. 生产消费者第一版: ...