Finally 与 return

网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正确的,经过我试验,至少有两种情况下finally语句是不会被执行的:

(1)try语句没有被执行到,如在try语句之前就返回了,这样finally语句就不会执行,这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。

(2)在try块中有System.exit(0);这样的语句,System.exit(0);是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。

 

当然还有很多人探讨Finally语句的执行与return的关系,颇为让人迷惑,不知道finally语句是在try的return之前执行还是之后执行?我也是一头雾水,我觉得他们的说法都不正确,我觉得应该是:finally语句是在try的return语句执行之后,return返回之前执行。这样的说法有点矛盾,也许是我表述不太清楚,下面我给出自己试验的一些结果和示例进行佐证,有什么问题欢迎大家提出来。

1. finally语句在return语句执行之后return返回之前执行的。

复制代码
public class FinallyTest1 {public static void main(String[] args) {System.out.println(test1());}public static int test1() {int b = 20;try {System.out.println("try block");return b += 80; }catch (Exception e) {System.out.println("catch block");}finally {System.out.println("finally block");if (b > 25) {System.out.println("b>25, b = " + b);}}return b;}}
复制代码

运行结果是:

try block
finally block
b>25, b = 100
100

说明return语句已经执行了再去执行finally语句,不过并没有直接返回,而是等finally语句执行完了再返回结果。

如果觉得这个例子还不足以说明这个情况的话,下面再加个例子加强证明结论:

复制代码
public class FinallyTest1 {public static void main(String[] args) {System.out.println(test11());}public static String test11() {try {System.out.println("try block");return test12();} finally {System.out.println("finally block");}}public static String test12() {System.out.println("return statement");return "after return";}}
复制代码

运行结果为:

try block
return statement
finally block
after return

说明try中的return语句先执行了但并没有立即返回,等到finally执行结束后再

这里大家可能会想:如果finally里也有return语句,那么是不是就直接返回了,try中的return就不能返回了?看下面。

2. finally块中的return语句会覆盖try块中的return返回。

复制代码
public class FinallyTest2 {public static void main(String[] args) {System.out.println(test2());}public static int test2() {int b = 20;try {System.out.println("try block");return b += 80;} catch (Exception e) {System.out.println("catch block");} finally {System.out.println("finally block");if (b > 25) {System.out.println("b>25, b = " + b);}return 200;}// return b;}}
复制代码

运行结果是:

try block
finally block
b>25, b = 100
200

这说明finally里的return直接返回了,就不管try中是否还有返回语句,这里还有个小细节需要注意,finally里加上return过后,finally外面的return b就变成不可到达语句了,也就是永远不能被执行到,所以需要注释掉否则编译器报错。

这里大家可能又想:如果finally里没有return语句,但修改了b的值,那么try中return返回的是修改后的值还是原值?看下面。

3. 如果finally语句中没有return语句覆盖返回值,那么原来的返回值可能因为finally里的修改而改变也可能不变。

测试用例1:

复制代码
public class FinallyTest3 {public static void main(String[] args) {System.out.println(test3());}public static int test3() {int b = 20;try {System.out.println("try block");return b += 80;} catch (Exception e) {System.out.println("catch block");} finally {System.out.println("finally block");if (b > 25) {System.out.println("b>25, b = " + b);}b = 150;}return 2000;}}
复制代码

运行结果是:

try block
finally block
b>25, b = 100
100

 

 

测试用例2:

 

复制代码
import java.util.*;public class FinallyTest6
{public static void main(String[] args) {System.out.println(getMap().get("KEY").toString());}public static Map<String, String> getMap() {Map<String, String> map = new HashMap<String, String>();map.put("KEY", "INIT");try {map.put("KEY", "TRY");return map;}catch (Exception e) {map.put("KEY", "CATCH");}finally {map.put("KEY", "FINALLY");map = null;}return map;}
}
复制代码

运行结果是:

FINALLY

为什么测试用例1中finally里的b = 150;并没有起到作用而测试用例2中finally的map.put("KEY", "FINALLY");起了作用而map = null;却没起作用呢?这就是Java到底是传值还是传址的问题了,具体请看精选30道Java笔试题解答,里面有详细的解答,简单来说就是:Java中只有传值没有传址,这也是为什么map = null这句不起作用。这同时也说明了返回语句是try中的return语句而不是 finally外面的return b;这句,不相信的话可以试下,将return b;改为return 294,对原来的结果没有一点影响。

这里大家可能又要想:是不是每次返回的一定是try中的return语句呢?那么finally外的return b不是一点作用没吗?请看下面。

4. try块里的return语句在异常的情况下不会被执行,这样具体返回哪个看情况。

复制代码
public class FinallyTest4 {public static void main(String[] args) {System.out.println(test4());}public static int test4() {int b = 20;try {System.out.println("try block");b = b / 0;return b += 80;} catch (Exception e) {b += 15;System.out.println("catch block");} finally {System.out.println("finally block");if (b > 25) {System.out.println("b>25, b = " + b);}b += 50;}return 204;}}
复制代码

运行结果是:

try block
catch block
finally block
b>25, b = 35
85
这里因 为在return之前发生了除0异常,所以try中的return不会被执行到,而是接着执行捕获异常的catch 语句和最终的finally语句,此时两者对b的修改都影响了最终的返回值,这时return b;就起到作用了。当然如果你这里将return b改为return 300什么的,最后返回的就是300,这毋庸置疑。

这里大家可能又有疑问:如果catch中有return语句呢?当然只有在异常的情况下才有可能会执行,那么是在finally之前就返回吗?看下面。

5. 当发生异常后,catch中的return执行情况与未发生异常时try中return的执行情况完全一样。

复制代码
public class FinallyTest5 {public static void main(String[] args) {System.out.println(test5());}public static int test5() {int b = 20;try {System.out.println("try block");b = b /0;return b += 80;} catch (Exception e) {System.out.println("catch block");return b += 15;} finally {System.out.println("finally block");if (b > 25) {System.out.println("b>25, b = " + b);}b += 50;}//return b;}}
复制代码

运行结果如下:

try block
catch block
finally block
b>25, b = 35
35

说明了发生异常后,catch中的return语句先执行,确定了返回值后再去执行finally块,执行完了catch再返回,finally里对b的改变对返回值无影响,原因同前面一样,也就是说情况与try中的return语句执行完全一样。

 

最后总结:finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中 return已经确定的返回值,若finally里也有return语句则覆盖try或catch中的return语句直接返回。

转载于:https://www.cnblogs.com/ziq711/p/5597443.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue表单的基本使用

Vue.js 表单 介绍 一下Vue.js 表单上的应用。你可以用 v-model 指令在表单控件元素上创建双向数据绑定。 v-model 会根据控件类型自动选取正确的方法来更新元素。 input 和 textarea 元素中使用 v-model 实现双向数据绑定: <!DOCTYPE html> <html> <head…

fold函数_Java中使用Map and Fold进行函数式编程

fold函数在函数式编程中&#xff0c;Map和Fold是两个非常有用的运算符&#xff0c;它们属于每种函数式语言。 如果Map和Fold运算符是如此强大且必不可少&#xff0c;那么您如何解释说即使Java编程语言缺少这两个运算符&#xff0c;我们也可以使用Java来完成工作&#xff1f; 事…

NVIC优先级分组

挂起&#xff0c;解挂&#xff0c;使能&#xff0c;失能 转载于:https://www.cnblogs.com/alantechnique/p/5598374.html

【Egret】Wing3发布移动APP功能,打包APK流程以及会遇到的问题

流程&#xff1a;1.安装好wing 3&#xff0c;然后 插件——Egret项目工具——发布移动APP——Build android native project 2.配置发布环境&#xff1a; Android 1.egret engine 点击下载2.android sdk mac版下载 windows版下载3.java sdk mac版下载 windows版…

有效运维的 on-call 机制

[编者按]本文作者为云告警平台OneAlert负责人&#xff0c;著《云计算与OpenStack》&#xff0c;在IT运营管理、云计算方面从业10多年。 正文 互联网技术的发展&#xff0c;离不开运维支撑工作&#xff0c;没有零bug的程序&#xff0c;没有不出问题的系统&#xff0c;问题故障不…

团队项目:界面设计

游戏内关卡为2D横版界面&#xff0c;背景为楼群贴图&#xff0c;整体色调以灰色为主&#xff0c;与摩托车手的主题相配。游戏中配有音效及背景音乐&#xff0c;背景音乐为我组成员自行创作录制完成。界面展示如下&#xff1a; 图1 游戏中设计图 图中显示的摩托车手即为玩家操控…

Hystrix简介

在过去的几天里&#xff0c;我一直在探索Netflix Hystrix库&#xff0c;并欣赏了这个出色的库所提供的功能。 引用Hystrix网站上的内容&#xff1a; Hystrix是一个延迟和容错库&#xff0c;旨在隔离对远程系统&#xff0c;服务和第三方库的访问点&#xff0c;停止级联故障&am…

MP3音乐播放器搜索引擎-鼠标拖动窗口

定义鼠标的按压&#xff0c;移动&#xff0c;施放事件 &#xff08;1&#xff09;鼠标的按压事件 globalpos是全局坐标&#xff0c;即鼠标相对于桌面屏幕左上角的坐标我们通过this->frameGeometry().topLeft();可以获得当前窗口的左上角的x左边或y坐标 在移动事件中我们可以…

SpringMVC学习--文件上传

简介文件上传是web开发中常见的需求之一&#xff0c;springMVC将文件上传进行了集成&#xff0c;可以方便快捷的进行开发。 springmvc中对多部件类型解析在 页面form中提交enctype"multipart/form-data"的数据时&#xff0c;需要springmvc对multipart类型的数据进行解…

VS code常用的快捷键

在前端的开发过程中&#xff0c;如果有一个比较好的开发工具&#xff0c;配合一些常用的快捷键&#xff0c;开发效率将大大提升&#xff0c;正所谓工具善其事必先利其器。前端推荐使用编辑器VS code,用过HB-X&#xff0c;ST3,Webstorm等编译器之后就会发现&#xff0c;前端编辑…

平台日志架构说明log4j漏洞问题解析

Log4j是Apache的一个开源项目&#xff0c;通过使用Log4j&#xff0c;我们可以控制日志信息输送的目的地是控制台、文件、GUI组件&#xff0c;甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等&#xff1b;我们也可以控制每一条日志的输出格式&#xff1b;通过定义每…

2016/06/22 中色启动筹码分析作业

2016/06/22 中色启动筹码分析作业——待核实 201转载于:https://www.cnblogs.com/carl2380/p/5608596.html

浏览器各个属性的作用

作为前端程序员不可避免的会和浏览器打交道&#xff0c;所以要对浏览器的各个属性的作用进行了解&#xff0c;方便开发及调试&#xff0c;这里以谷歌浏览器为例进行简单的介绍。一是巩固对浏览器属性的认识&#xff0c;二是方便大家的学习。首先打开谷歌浏览器按F12查看控制台属…

Moment.js日期处理库的使用

Moment.jsMoment.js是一个轻量级的JavaScript时间库&#xff0c;它方便了日常开发中对时间的操作&#xff0c;提高了开发效率。这个在一些金融保险公司会经常用到&#xff0c;比如一下时间的格式化处理&#xff0c;时间的选择等等。这个比较好的地方是可以格式化时间&#xff0…

转: 微博的多机房部署的实践(from infoq)

转: http://www.infoq.com/cn/articles/weibo-multi-idc-architecture 在国内网络环境下&#xff0c;单机房的可靠性无法满足大型互联网服务的要求&#xff0c;如机房掉电&#xff0c;光缆被挖的情况也发生过。微信就曾发生大面积故障&#xff0c;包括微信信息无法发出、无法刷…

知道这些性能优化手段,工资起码提升一倍

1.什么是性能?性能指标有哪些&#xff1f;计算机的性能&#xff0c;其实和我们干体力劳动很像&#xff0c;好比是我们要搬东西。对于计算机的性能&#xff0c;我们需要有个标准来衡量。这个标准中主要有两个指标。第一个是响应时间&#xff08;Response time&#xff09;或者叫…

亲手把360奇安信软件卸载了,爽!

由于工作原因&#xff0c;在上一家公司安装了360奇安信安全软件&#xff0c;到了下一个公司还需要安装另一个安全软件&#xff0c;这个必须要卸载&#xff0c;卸载&#xff01;卸载&#xff01;但是卸载需要输入密码&#xff0c;没有密码还输入卸载不了&#xff0c;我曾经联系3…

VM虚拟机中CentOS6.4操作系统安装一

在 VMware中鼠标单击“编辑虚拟机设置”&#xff0c;在弹出的“虚拟机设置”对话框中的“硬件”标签中选择“CD/DVD&#xff08;IDE&#xff09;”&#xff0c;然后在右侧的“CD /DVD&#xff08;IDE&#xff09;”连接选项中选择“使用ISO映像文件”&#xff0c;使用“浏览”按…

vue基础教程总结篇,用最短的时间入门vue.js(持续更新...)

目前&#xff0c;vue已经成为前端工程师必会的框架之一&#xff0c;这里简单总结一下&#xff0c;可以让您快速的入门vue,师傅带进门&#xff0c;修行靠个人&#xff0c;最主要的还是自己多动手&#xff0c;多实践&#xff0c;本专栏会持续更新。 1.vue安装教程及简介 2.vue计…

关于SP一些响应码的API返回码及解析集合

在一些金融的行业&#xff08;银行、证券、保险等&#xff09;&#xff0c;如果接触了一些中间件&#xff0c;比如长城、恒银、广电等一些厂商的设备&#xff0c;不同的厂商有不同的一些规范&#xff0c;在应用开发的过程中难免会和中间件的错误码打交道&#xff0c;这里总结一…