我敢说你不一定完全理解try 块,catch块,finally 块中return的执行顺序
大家好,今天我们来讲一个笔试和面试偶尔都会问到的问题,并且在工作中不知道原理,也会造成滥用。
大家可能都知道,try 块用来捕获异常,catch块是处理try块捕获的异常,finally 块是用来关闭资源。一个try块后面可以跟多个catch块,如果后面一个catch块也不跟,就一定要跟一个finally 块。
结论1:当在try块遇到return语句时,finally语句块将在方法返回之前被执行,但是返回值不受finally块中重新赋值的影响。
public class FinallyTest {
public static void main(String[] args) throws Exception {
int a = 10;
int sum = throwException(a);
System.out.println("执行返回结果sum:" + sum);
} public static int throwException(int a) throws Exception{
int b = 20;
int result = 0;
try{
System.out.println("执行try语句块");
result = a+b;
return result;
}catch(Exception e){
System.out.println("执行catch语句块");
}finally{
System.out.println("执行finally语句块");
result = 1;
}
return result;
}
}
结论2:当在catch块遇到return或者throw异常语句时,finally语句块将在方法返回之前被执行,但是返回值不受finally块中重新赋值的影响。
public class FinallyTest {
public static void main(String[] args) throws Exception {
int a = 10;
int sum = throwException(a);
System.out.println("执行返回结果sum:" + sum);
} public static int throwException(int a) throws Exception{
int b = 20;
int result = 0;
try{
System.out.println("执行try语句块");
result = b / 0;
return result;
}catch(Exception e){
System.out.println("执行catch语句块");
return result;
}finally{
System.out.println("执行finally语句块");
result = 1;
} }
}
结论3:如果try,finally语句里均有return,忽略try的return值,而使用finally的return值
public class FinallyTest {
public static void main(String[] args) throws Exception {
int a = 10;
int sum = throwException(a);
System.out.println("执行返回结果sum:" + sum);
} public static int throwException(int a) throws Exception{
int b = 20;
int result = 0;
try{
System.out.println("执行try语句块");
result = a + b;
return result;
}catch(Exception e){
System.out.println("执行catch语句块");
}finally{
System.out.println("执行finally语句块");
result = 1; return result;
} }
}
结论4 :在finally语句块发生了异常,finanly语句块中异常后面的代码不会再执行。
public class FinallyTest {
public static void main(String[] args) throws Exception {
int a = 10;
int sum = throwException(a);
System.out.println("执行返回结果sum:" + sum);
} public static int throwException(int a) throws Exception{
int result = 30;
try{
System.out.println("执行try语句块");
return result;
}catch(Exception e){
System.out.println("执行catch语句块");
}finally{
int exception = b / 0;
System.out.println("执行finally语句块");
result = 1;
}
return result;
}
}
结论5:try语句块发生异常,并且finally语句块也发生了异常,finally块中的异常会掩盖try块中的异常。
public class FinallyTest {
public static void main(String[] args) throws Exception {
int a = 10;
int sum = throwException(a);
System.out.println("执行返回结果sum:" + sum);
} public static int throwException(int a) throws Exception{
int result = 0;
try{
System.out.println("执行try语句块");
result = a / 0 ;
return result;
}catch(Exception e){
throw new Exception(e);
}finally{
int[] arr = new int[1];
arr[2] = 3;
System.out.println("执行finally语句块");
}
}
}
通过上面的5个案例,我们应该对try 块,catch块,finally 块中return的执行顺序有了清晰的理解,下面我们在进行总结一下。
1. 当在try块遇到return语句时,finally语句块将在方法返回之前被执行,但是返回值不受finally块中重新赋值的影响。
2. 当在catch块遇到return或者throw异常语句时,finally语句块将在方法返回之前被执行,但是返回值不受finally块中重新赋值的影响。
3. 如果try,finally语句里均有return,忽略try的return,而使用finally的return。
4 . 在finally语句块发生了异常,finanly语句块异常后面的代码不会在执行。
5:try{}语句块发生异常,并且finally语句块也发生了异常,finally块中的异常会掩盖try块中的异常。
另外,关于1,2两点,不受finally块影响的原理,我做一个补充,为什么在finally块改变try块中的返回值,结果不受影响了?
如果try语句里有return,返回的是try语句块中的局部变量值。 详细执行过程如下:
①首先我们在try快中,会把返回值保存到局部变量中;
② 然后执行jsr指令跳到finally语句里执行;
③ 执行完finally语句后,返回之前保存在局部变量表里的值,所以finally块里改变try块中的返回值,不会生效。(但是上面第3点场景,finally自己带return返回值除外)
感谢大家的观看,如有错误之处,欢迎指出,共同学习,共同进步~
如果大家看我的文章觉得有所收获,请将文章分享给你们的朋友,后续我会更新更多浅显,优质的技术文章!
我敢说你不一定完全理解try 块,catch块,finally 块中return的执行顺序的更多相关文章
- 浅谈个人对客户端JavaScript同步、异步、执行顺序等概念的理解
一.同步和异步的概念. 同步:即按代码的顺序执行任务. 在下列代码中,按照同步概念,则是先打印1后打印2. console.log(1); console.log(2); 异步:即执行一个任务的同时执 ...
- 【repost】js中(function(){…})()立即执行函数写法理解
摘要: javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解. ...
- js中(function(){…})()立即执行函数写法理解
文章摘自https://my.oschina.net/u/2331760/blog/468672?p={{currentPage+1}} 摘要: javascript和其他编程语言相比比较随意,所以j ...
- 简单理解Struts2中拦截器与过滤器的区别及执行顺序
简单理解Struts2中拦截器与过滤器的区别及执行顺序 当接收到一个httprequest , a) 当外部的httpservletrequest到来时 b) 初始到了servlet容器 传递给一个标 ...
- 深入理解javascript中的立即执行函数(function(){…})()
投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...
- C++-理解构造函数、析构函数执行顺序
先初始化序列中的函数调用,如果基类构造函数为非引用传递,则引起参数的拷贝构造 再: 先类内的成员构造函数(拷贝/默认),再类的构造函数:先基类,再派生类: 本文主要说明对象创建时构造函数的执行顺序,对 ...
- IIFE-js中(function(){…})()立即执行函数写法理解
介绍IIFE IIFE的性能 使用IIFE的好处 IIFE最佳实践 jQuery优化 在Bootstrap源码(具体请看<Bootstrap源码解析>)和其他jQuery插件经常看到如下的 ...
- mirantis fuel puppet执行顺序 和 对整个项目代码的执行流程理解
stage执行顺序 stage {'zero': } -> stage {'first': } -> stage {'openstack-custom-repo': } -> sta ...
- junit4X系列源码--Junit4 Runner以及test case执行顺序和源代码理解
原文出处:http://www.cnblogs.com/caoyuanzhanlang/p/3534846.html.感谢作者的无私分享. 前一篇文章我们总体介绍了Junit4的用法以及一些简单的测试 ...
随机推荐
- python爬虫人门(10)Scrapy框架之Downloader Middlewares
设置下载中间件(Downloader Middlewares) 下载中间件是处于引擎(crawler.engine)和下载器(crawler.engine.download())之间的一层组件,可以有 ...
- java算法之超级丑数
问题描述: 写一个程序来找第 n 个超级丑数. 超级丑数的定义是正整数并且所有的质数因子都在所给定的一个大小为 k 的质数集合内. 比如给你 4 个质数的集合 [2, 7, 13, 19], 那么 [ ...
- Python并发编程之线程消息通信机制任务协调(四)
大家好,并发编程 进入第四篇. 本文目录 前言 Event事件 Condition Queue队列 总结 . 前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程 ...
- Java并发之Condition
在使用Lock之前,我们使用的最多的同步方式应该是synchronized关键字来实现同步方式了.配合Object的wait().notify()系列方法可以实现等待/通知模式.Condition接口 ...
- Design5:SQL Server 文件和文件组
数据库是数据的仓库,用于存储数据,而存储数据需要媒介,现在的存储媒介,最常用的是硬盘,土豪一点的服务器使用固态硬盘(SSD),特殊用途的服务器使用内存.数据库最常用的存储文件是数据文件和日志文件,数据 ...
- java 各数据类型之间的转换
String —> Date SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date ...
- PHP生成腾讯云COS请求签名
目标 使用 PHP 创建 COS 接口所需要的请求签名 步骤 按照官方示例(也许是我笨,我怎么读都觉得官方文档结构费劲,示例细节互相不挨着,容易引起歧义),请求签名应用在需要身份校验的场景,即非公有读 ...
- thinkphp 自动生成模块目录结构
要达到的目的 在application目录下创建自定义模块如admin,用命令行方式自动创建该目录及目录下默认结构 要运行的命令 > php think build --module admin ...
- 几种扫描二维码工具的User-Agent
微信: user-agent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, ...
- Git请求合并说明
如今公司很多新项目都采取merge request方式来进行code review.非阻塞上线部署,因此掌握merge request很有必要,步骤如下: 1.现在本地用创建一个本地分支, git c ...