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中使用JDBC
在hibernate中获取connection数据库连接有两种方法:(操作数据库常用这种方法) 1. session.doReturningWork 返回一个对象,适用于查询方法 2. sessi ...
- Java ShellSort
Java ShellSort /** * <html> * <body> * <P> Copyright 1994-2018 JasonInternational ...
- C# Winform 设置窗口打开的特效
https://www.cnblogs.com/mq0036/p/6421946.html using System.Runtime.InteropServices; public class Win ...
- 十三、Vue中的computed属性
以下抄自https://www.cnblogs.com/gunelark/p/8492468.html 看了网上很多资料,对vue的computed讲解自己看的都不是很清晰,今天忙里抽闲,和同事们又闲 ...
- C++ raw string literal
raw string literal 以 R"( 开头, )" 结束,是可以跨越多行的字符串字面值,转义字符如 \t\n 在raw string literal中是普通的文本 ...
- Express无法解析POST请求的JSON参数
在用Express和MongoDB搭建后端开发环境时,可能会利用测试工具发送带有JSON格式数据的POST请求,那么这时就要利用request.body获取json数据,但此时可能遇到json无法解析 ...
- Unity 自定义"=="操作符 [翻译来源blogs.unity3d,2014/05]
主要内容来源 https://blogs.unity3d.com/cn/2014/05/16/custom-operator-should-we-keep-it/ 在我们代码里,如果有这样的代码: i ...
- STL源码剖析 - RB-tree
在我看来,看源码是一件既痛苦又兴奋的事.当我们在推敲其中的难点时,是及其痛苦的,但当发现实现代码是那么丝滑简洁时,“wc, nb!”. 1. 导语 如果我们去看关联式容器map.set.multima ...
- Redis二进制安全概念
二进制安全是指,在传输数据时,保证二进制数据的信息安全,也就是不被篡改.破译等,如果被攻击,能够及时检测出来. 二进制安全包含了密码学的一些东西,比如加解密.签名等. 举个例子,你把数据1111000 ...
- Computer Vision_33_SIFT:Object recognition from local scale-invariant features——1999
此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...