我敢说你不一定完全理解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的用法以及一些简单的测试 ...
随机推荐
- 团队项目第二阶段个人进展——Day3
一.昨天工作总结 冲刺第三天,基本完成发布页面的布局 二.遇到的问题 添加照片的样式会随照片增加而改变 三.今日工作规划 分析要封装的数据有哪些,数据如何传到后端服务器中
- Python_FTP通讯软件
ftpServer.py import socket import threading import os import struct #用户账号.密码.主目录 #也可以把这些信息存放到数据库中 us ...
- Python_heapq
import heapq #导入heapq堆模块 import random data = random.sample(range(1000),10) print(data) heapq.heapif ...
- IM进化论:腾讯也难逃被颠覆掉的命运
在一定程度上,腾讯代表了中国IM领域的过去和未来.但有句俗话,后来推前浪,前浪被拍死在沙滩上,"生死腾讯"也总会变为生和死,因为腾讯很可能会有被颠覆掉的一天.腾讯的IM接口是个庞然 ...
- SpringMVC中的拦截器
1. 自定义拦截器 实现HandlerInterceptor接口 拦截器一: package cn.rodge.ssm.interceptor;import javax.servlet.http.Ht ...
- 【原】用Java编写第一个区块链(一)
写这篇随笔主要是尝试帮助自己了解如何学习区块链技术开发. [本文禁止任何形式的全文粘贴式转载,本文来自 zacky31 的随笔] 目标: 创建一个最基本的"区块链" 实现一个简单的 ...
- 在 Docker 容器中运行应用程序
案例说明 运行 3 个容器,实现对网站的监控. 三个容器的说明: 容器 web: 创建自 nginx 映像,使用 80 端口,运行于后台,实现 web 服务. 容器 mailer: 该容器中运行一个 ...
- MD5加密算法(java及js)
为了防止用户登陆过程中信息被拦截导致信息泄露,我们应该在客户端就对用户密码进行加密.浏览器提交给服务器的是加密后的信息,即使被恶意拦截,被拦截信息也已做了加密处理,现在比较安全的一种加密算法是MD5加 ...
- 【爬虫】Xpath高级用法
xpath速度比较快,是爬虫在网页定位中的较优选择,但是很多网页前端代码混乱难以定位,而学习定位也较为不易(主要是全面的教程较少),这里列出一点编程过程中可能有用的东西,欢迎共同学习批评指正.试验环境 ...
- 连接Redis后执行命令错误 MISCONF Redis is configured to save RDB snapshots
今天在redis中执行setrange name 1 chun 命令时报了如下错误提示: (error) MISCONF Redis is configured to save RDB snapsho ...