当try-catch-finally代码块遇上return,代码执行流程是怎样
这里打算用一个Java读取文件内容的例子来测试,文件存在,不抛异常,文件不存在,则抛出FileNotFoundException;
Java读取文件代码如下:
/**
* 根据路径和文件名获取内容
* @param filePath
* @param fileName
* @return
*/
public Object findFileContentByName(String filePath, String fileName) {
InputStream in = null;
Scanner scanner = null;
try {
in = new FileInputStream(filePath + "/" + fileName);
scanner = new Scanner(in);
StringBuffer stringBuffer = new StringBuffer();
if(scanner.hasNext()){
String s = scanner.nextLine();
stringBuffer.append(s).append("\n");
} log.info("stringBuffer.toString()");
return stringBuffer.toString(); }catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
log.info("Close stream!");
try {
if(scanner != null){
scanner.close();
} if(in != null){
in.close();
}
}catch (IOException e){
e.printStackTrace();
} } log.info("Preparing return null");
return null;
}
代码很简单,就是传入文件的路径和文件名(包括文件后缀名),来获取文件内容;
当我们传入一个在该路径下存在的文件时,不会抛异常,日志如下图:

当我们传入一个不存在该路径下的文件时,会抛出异常,日志如下图(堆栈信息太长只截取了部分):


当我们在catch语句块中加入了return,这时我们传入一个不存在该路径下的文件时,会抛出异常,执行完finally(不要在finally代码会中写return)会立即执行catch中的return,则该函数终止:
public Object findFileContentByName(String filePath, String fileName) {
InputStream in = null;
Scanner scanner = null;
try {
in = new FileInputStream(filePath + "/" + fileName);
scanner = new Scanner(in);
StringBuffer stringBuffer = new StringBuffer();
if (scanner.hasNext()){
String s = scanner.nextLine();
stringBuffer.append(s).append("\n");
}
log.info("stringBuffer.toString()");
return stringBuffer.toString();
}catch (FileNotFoundException e){
log.info("catch FileNotFoundException e");
e.printStackTrace();
return "catch FileNotFoundException e";
} catch (IOException e) {
e.printStackTrace();
} finally {
log.info("Close stream!");
try {
if(scanner != null){
scanner.close();
}
if(in != null){
in.close();
}
}catch (IOException e){
e.printStackTrace();
}
// 不要在finally块中使用return,finally块中的return返回后方法结束执行,不会再执行try块中的return语句。
}
log.info("Preparing return null");
return null;
}


总结
在try-catch-finally代码块中,有多个return时:
如果代码没有抛出异常,以第一个return返回(本例中的return在try中),并且finally代码块还会被执行;
如果代码块抛出异常,应该也是以第一个return返回,并且finally代码块还会被执行;
finally代码块的执行不一定是最后执行的,比如本例子中,由于抛出异常后,无return,接着执行finally,finally代码块执行完后,函数还有代码,打印了日志,然后return null。
总的来说,不管代码有没有抛出异常,代码块执行的顺序是:
如果代码执行到第一个return时,未执行finally代码块,则执行完第一个return,紧接着执行finally代码块,执行完finally后,不再执行该函数任何代码;
如果代码执行到第一个return时,已经执行完finally代码块,则紧接着执行第一个return后,不再执行该函数任何代码;
如果finally函数代码块后面没代码,则执行finally代码块后,不再执行该函数任何代码;
注意:第一个return不是函数代码的顺序,而是代码执行过程中遇到的第一个return!
不要在finally块中使用return,finally块中的return返回后,方法结束执行,不会再执行try块中的return语句。
当try-catch-finally代码块遇上return,代码执行流程是怎样的更多相关文章
- final、static、代码块、静态代码块、内部类、代码执行顺序
final final域使得确保初始化安全性(initialization safety)成为可能,初始化安全性让不可变形对象不需要同步就能自由地被访问和共享 作用在类上 ...
- 关于java构造函数,静态代码块,构造代码块,和普通代码块相关总结(一)
构造函数.构造代码块和静态代码块容易混淆,它们的执行条件和执行顺序也常常容易犯迷.这里就针对这些问题说一下我个人的一些理解,顺便对这部分内容做个小结. 一.构造函数 格式:类名(参数1,参数2,-){ ...
- java中静态代码块,构造代码块,以及构造方法的执行顺序
写了许久的代码,却把一些基础的东西都给忘了,今天无聊就顺手写了个,然后测试下,发现跟我记忆中的竟然有些出入,作为一个两年的开发,我感觉自己很失败啊. 父类pojo: public class Pojo ...
- java 代码块,静态代码块,构造器等的执行顺序
写了一段测试代码,如下: public class ExecutionSequence extends fatherClass{ static{ System.out.printl ...
- java中普通代码块,构造代码块,静态代码块的区别及代码示例
本文转自:http://www.cnblogs.com/sophine/p/3531282.html 执行顺序:(优先级从高到低)静态代码块>main方法>构造代码块>构造方法. 其 ...
- 构造代码块、构造函数、this执行顺序
一.构造函数 对象一建立就会调用与之对应的构造函数. 构造函数的作用:可以用于给对象进行初始化. 构造函数的小细节:当一个类中没有定义构造函数时,系统会默认给该类加一个空参数的构造函数:当在类中自定义 ...
- JAVA程序执行顺序(静态代码块》非静态代码块》静态方法》构造函数)
总结:静态代码块总是最先执行. 非静态代码块跟非静态方法一样,跟对象有关.只不过非静态代码块在构造函数之前执行. 父类非静态代码块.构造函数执行完毕后(相当于父类对象初始化完成), 才开始执行子类的非 ...
- java中静态代码块,非静态代码块,构造函数
关于静态代码块 静态代码块的写法: static { System.out.println("我是静态代码块"); } 静态代码块的特点: 1.执行优先级高于非静态的初始化块,它会 ...
- try、catch、finally--try块里有return,finally还执行吗?
finally块的作用是,保证无论出现什么情况,finally块里的代码一定会被执行. 由于程序执行return就意味着结束对当前函数的调用并跳出这个函数体,所以任何语句要执行都只能在return之前 ...
随机推荐
- Linux TCP/IP调优-Linux内核参数注释
固定文件的内核参数 下列文件所在目录: /proc/sys/net/ipv4/ 名称 默认值 建议值 描述 tcpsyn_retries 5 1 对于一个新建连接,内核要发送多少个SYN连接请求才决定 ...
- Django实现瀑布流,组合搜索
Django中组合搜索功能 需求分析 很多电商网站中有组合搜索的功能,所谓组合搜索就是网页中组合多个条件,对数据库中进行查询,并且将结果显示在页面中,看个例子吧: 注意红框中的标识,我们可以根据URL ...
- QT学习之QT5.7+opencv3.1安装及显示图像
如果有时间就按照这篇博文一步一步走: http://www.cnblogs.com/howlclat/p/6433097.html, 如果没时间: 直接下载最后的文件就可以了,不要浪费时间再去编译,真 ...
- linux系统 python升级创建虚拟环境
Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替之前的virtualenv. 该venv模块提供了创建轻量级“虚拟环境”,提供与系统Python的隔离支持.每一个虚拟环境都有其自 ...
- 【Python】python3 正则爬取网页输出中文乱码解决
爬取网页时候print输出的时候有中文输出乱码 例如: \\xe4\\xb8\\xad\\xe5\\x8d\\x8e\\xe4\\xb9\\xa6\\xe5\\xb1\\x80 #爬取https:// ...
- Exchange重启脚本
Much more from the source article itself ...... details or code stated above http://therealshrimp.bl ...
- js: 字符集
用js生成字符集 一般网页制作中需要一些向上向下的小箭头,用图片非常不合算(一个页面发起多个http请求.css.文件大小等方面考虑) 所以用一些字符集的字符图形,效果很好 下面是用js生成字符集,以 ...
- vue语法小练习
实现功能:新增/删除 学生 <html> <head> <script src="https://cdn.staticfile.org/vue/2.2.2/vu ...
- PHP 支持 JQuery 的 JSONP 跨域访问
Jquery Ajax进行跨域时需要使用JSONP,但JSONP格式和JSON格式是有区别的,如果直接返回JSON格式就会报错 首先将原有的Jquery代码中的dataType改成“jsonp”,具体 ...
- day02-数据库操作
一.数据库操作 1.1.创建数据库(增) CREATE DATABASE 也可以使用小写,(注意不要漏掉分号 ;) mysql> create database test; 或 mysql> ...