异常 try catch finally return 执行关系 MD
Markdown版本笔记 | 我的GitHub首页 | 我的博客 | 我的微信 | 我的邮箱 |
---|---|---|---|---|
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
异常 try catch finally return 执行关系 MD
目录
探讨finally语句的执行与return的关系
Java异常捕获机制try...catch...finally
块中的finally
语句是不是一定会被执行?不一定,至少有两种情况下finally语句是不会被执行的:
- try语句没有被执行到,如在try语句之前就返回了,这样finally语句就不会执行,这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。
- 在try块中有
System.exit(0)
这样的语句,System.exit(0)
是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。
1、finally语句是在try的return语句执行之后,return返回之前执行的
测试案例:
public class TestFinally {
public static void main(String[] args) {
System.out.println(test());
}
public static String test() {
try {
System.out.println("try block");
if (new Random().nextBoolean()) {
return "直接返回";
} else {
return test2();
}
} finally {
System.out.println("finally block");
}
}
public static String test2() {
System.out.println("return statement");
return "调用方法返回";
}
}
运行结果:
try block
finally block
直接返回
或
try block
return statement
finally block
调用方法返回
说明try中的return语句先执行了,但并没有立即返回,而是等到finally执行结束后再返回。
这里大家可能会想:如果finally里也有return语句,那么是不是就直接返回了,try中的return就不能返回了?看下面。
2、finally块中的return语句会覆盖try块中的return返回
public class TestFinally {
public static void main(String[] args) {
System.out.println(test());
}
public static String test() {
try {
System.out.println("try block");
return "在try中返回";
} finally {
System.out.println("finally block");
return "在finally中返回";
}
// return "finally外面的return就变成不可到达语句,需要注释掉否则编译器报错";
}
}
运行结果:
try block
finally block
在finally中返回
这说明finally里的return直接返回了,就不管try中是否还有返回语句。
这里还有个小细节需要注意,finally里加上return过后,finally外面的return b就变成不可到达语句了,也就是永远不能被执行到,所以需要注释掉否则编译器报错。
3、如果finally语句中没有return语句覆盖返回值,那么原来的返回值可能因为finally里的修改而改变,也可能不变
测试用例:
public class TestFinally {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
int b = 20;
try {
System.out.println("try block");
return b += 80;
} finally {
b += 10;
System.out.println("finally block");
}
}
}
运行结果:
try block
finally block
100
测试用例2:
public class TestFinally {
public static void main(String[] args) {
System.out.println(test());
}
public static List<Integer> test() {
List<Integer> list = new ArrayList<Integer>();
list.add(10086);
try {
System.out.println("try block");
return list;
} finally {
list.add(10088);
System.out.println("finally block");
}
}
}
运行结果:
try block
finally block
[10086, 10088]
这其实就是Java到底是传值还是传址的问题了,简单来说就是:Java中只有传值没有传址。
这里大家可能又要想:是不是每次返回的一定是try中的return语句呢?那么finally外的return不是一点作用没吗?请看下面
4、try块里的return语句在异常的情况下不会被执行,这样具体返回哪个看情况
public class TestFinally {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
int b = 0;
try {
System.out.println("try block");
b = b / 0;
return b += 1;
} catch (Exception e) {
b += 10;
System.out.println("catch block");
} finally {
b += 100;
System.out.println("finally block");
}
return b;
}
}
运行结果是:
try block
catch block
finally block
110
这里因 为在return之前发生了异常,所以try中的return不会被执行到
,而是接着执行捕获异常的 catch 语句和最终的 finally 语句,此时两者对b的修改都影响了最终的返回值,这时最后的 return b 就起到作用了。
这里大家可能又有疑问:如果catch中有return语句呢?当然只有在异常的情况下才有可能会执行,那么是在 finally 之前就返回吗?看下面。
5、当发生异常后,catch中的return执行情况与未发生异常时try中return的执行情况完全一样
public class TestFinally {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
int b = 0;
try {
System.out.println("try block");
b = b / 0;
return b += 1;
} catch (Exception e) {
b += 10;
System.out.println("catch block");
return 10086;
} finally {
b += 100;
System.out.println("finally block");
}
//return b;
}
}
运行结果:
try block
catch block
finally block
10086
说明了发生异常后,catch中的return语句先执行,确定了返回值后再去执行finally块,执行完了catch再返回,也就是说情况与try中的return语句执行完全一样。
总结:
- finally块的语句在try或catch中的return语句执行之后返回之前执行
- 且finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值
- 若finally里也有return语句则覆盖try或catch中的return语句直接返回
2019-3-4
异常 try catch finally return 执行关系 MD的更多相关文章
- finally return 执行关系 异常处理 c#
Return.finally执行关系简述 除了函数出现system.exit(0)终止虚拟机,finally中的代码一定执行,return语句会等待finally的执行:如果是值传递,finally中 ...
- java try catch finally return执行
public static int testBasic(){ int i = 1; try{ i++; System.out.println("try block, i = "+i ...
- try catch finally return之间的关系
一.try catch finally return之间的关系: 正在写dsoFramer的时候,同事突然说面试的时候问的一个问题,catch和return那个先执行,我瞬间迷茫了,然后整理了整理,稍 ...
- 有return的情况下try catch finally的执行顺序(转)
结论:1.不管有木有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没 ...
- try catch finally的执行顺序(有return的情况下)
结论:1.不管有木有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没 ...
- 有return的情况下try catch finally的执行顺序
结论:1.不管有木有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没 ...
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
结论:1.不管有木有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没 ...
- Java基础知识强化之IO流笔记06:有return的情况下try catch finally的执行顺序
1. 给出结论: (1)不管有木有出现异常,finally块中代码都会执行:(2)当try和catch中有return时,finally仍然会执行:(3)finally是在return后面的表达式运算 ...
- 【Java疑难杂症】有return的情况下try catch finally的执行顺序
有这样一个问题,异常处理大家应该都不陌生,类似如下代码: public class Test { public static void main(String[] args) { int d1 = 0 ...
随机推荐
- linux之常见命令
linux之常见命令 创建一个目录 /data mkdir /data ls -l /data/ cd /data/ pwd 相对路径与绝对路径 1.绝对路径 从根开始的路径 /data 2.相对路径 ...
- CentOS配置通过DHCP的方式动态获取IP
修改/etc/sysconfig/network NETWORKING=yes 修改/etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 ONBO ...
- DDD领域模型实现依赖注入(六)
添加下订单的值对象: public partial class CustomerInfo:ValueObject { /// <summary> /// 下订单的值对象 /// </ ...
- Timber(对Log类封装的一个工具)
Timber(对Log类封装的一个工具) https://blog.csdn.net/hzl9966/article/details/51314137 https://www.jianshu.com/ ...
- Android开发之实现多次点击事件
在Android中给我们提供了单次点击事件.但并没有给我们提供双击,或者实现在一定时间内的多次事件.所以需要我们自己在单机监听上进行修改实现. 有如下两种实现方式: 1.定义一个存贮上一个第一次点击的 ...
- huffman编解码英文文本[Python]
对英文文本的字母进行huffman编码,heapq优先队列构建huffman树 python huffman.py source.txt result.txt import sys import he ...
- 《Java程序性能优化》之设计优化
豆瓣读书:http://book.douban.com/subject/19969386/ 第一章 Java性能调优概述 1.性能的参考指标 执行时间: CPU时间: 内存分配: 磁盘吞吐量: 网络吞 ...
- 关闭swap的危害——一旦内存耗尽,由于没有SWAP的缓冲,系统会立即开始OOM
SWAP的罪与罚 发表于2012-11-08 说个案例:一台Apache服务器,由于其MaxClients参数设置过大,并且恰好又碰到访问量激增,结果内存被耗光,从而引发SWAP,进而负载攀升,最终导 ...
- 【Java】 剑指offer(35) 复杂链表的复制
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请实现函数ComplexListNode* Clone(Compl ...
- js获取、修改url中参数
//获取url的参数 function getParam(paramKey){ //获取当前URL var url = location.href; //获取要取得的get参数位置 var get = ...