这里打算用一个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,代码执行流程是怎样的更多相关文章

  1. final、static、代码块、静态代码块、内部类、代码执行顺序

    final final域使得确保初始化安全性(initialization safety)成为可能,初始化安全性让不可变形对象不需要同步就能自由地被访问和共享 作用在类上               ...

  2. 关于java构造函数,静态代码块,构造代码块,和普通代码块相关总结(一)

    构造函数.构造代码块和静态代码块容易混淆,它们的执行条件和执行顺序也常常容易犯迷.这里就针对这些问题说一下我个人的一些理解,顺便对这部分内容做个小结. 一.构造函数 格式:类名(参数1,参数2,-){ ...

  3. java中静态代码块,构造代码块,以及构造方法的执行顺序

    写了许久的代码,却把一些基础的东西都给忘了,今天无聊就顺手写了个,然后测试下,发现跟我记忆中的竟然有些出入,作为一个两年的开发,我感觉自己很失败啊. 父类pojo: public class Pojo ...

  4. java 代码块,静态代码块,构造器等的执行顺序

    写了一段测试代码,如下: public class ExecutionSequence extends fatherClass{    static{        System.out.printl ...

  5. java中普通代码块,构造代码块,静态代码块的区别及代码示例

    本文转自:http://www.cnblogs.com/sophine/p/3531282.html 执行顺序:(优先级从高到低)静态代码块>main方法>构造代码块>构造方法. 其 ...

  6. 构造代码块、构造函数、this执行顺序

    一.构造函数 对象一建立就会调用与之对应的构造函数. 构造函数的作用:可以用于给对象进行初始化. 构造函数的小细节:当一个类中没有定义构造函数时,系统会默认给该类加一个空参数的构造函数:当在类中自定义 ...

  7. JAVA程序执行顺序(静态代码块》非静态代码块》静态方法》构造函数)

    总结:静态代码块总是最先执行. 非静态代码块跟非静态方法一样,跟对象有关.只不过非静态代码块在构造函数之前执行. 父类非静态代码块.构造函数执行完毕后(相当于父类对象初始化完成), 才开始执行子类的非 ...

  8. java中静态代码块,非静态代码块,构造函数

    关于静态代码块 静态代码块的写法: static { System.out.println("我是静态代码块"); } 静态代码块的特点: 1.执行优先级高于非静态的初始化块,它会 ...

  9. try、catch、finally--try块里有return,finally还执行吗?

    finally块的作用是,保证无论出现什么情况,finally块里的代码一定会被执行. 由于程序执行return就意味着结束对当前函数的调用并跳出这个函数体,所以任何语句要执行都只能在return之前 ...

随机推荐

  1. 流(Stream)与文件流(FileStream)

    //通过流的方式添加 StreamWriter writer = new StreamWriter(@"C:\A\ca.txt", true, Encoding.Default); ...

  2. Vue学习记录(二)

    一.指令 指令是Vue.js中一个重要的特性,主要提供了一种机制将数据的变化映射为DOM行为.当数据变化时,指令会依据设定好的操作对DOM进行修改,这样就可以只关注数据的变化,而不用去管理DOM的变化 ...

  3. [CTSC2012]熟悉的文章 (后缀自动机 单调队列)

    /* 首先答案显然是具有单调性的, 所以可以二分进行判断 然后当我们二分过后考虑dp来求最长匹配个数, 发现每个点能够转移的地点 肯定是一段区间, 然后这样就能够得到一个log^2算法 至于每个点的匹 ...

  4. Python-1 试玩OpenCV

    昨天同事说微信更新有跳一跳小游戏,便更新了玩一玩.至于抄袭不抄袭我不讨论,看玩法和色彩都很简洁.想用Python试试摄像头捕捉图像,然后分析距离每次都能跳到中心,有生物机械手指之类的再弄到树莓派上岂不 ...

  5. kvm云主机使用宿主机usb设备

    有些时候KVM客户机还是要使用USB设备,比如USB密钥等 KVM命令行参数 -usb 打开usb驱动程序,启动客户机usb支持-usbdevice devname 为客户机增加usb设备,devna ...

  6. python中 将你的名字转化成为二进制并输出

    1 name = "吴彦祖" 2 for i in name: 3 i_by = bytes(i, encoding = "utf-8") 4 for i_bi ...

  7. IDEA Maven项目 编译的问题

    IDEA中,点击项目的maven插件的 compile: 出现: [INFO] ------------------------------------------------------------ ...

  8. <转载> GIT 操作小结 http://www.cnblogs.com/-ding/p/6008096.html

    参考: http://www.cnblogs.com/zyf-zhaoyafei/p/4486220.html 作者:万境绝尘 转载请注明出处:http://blog.csdn.net/shulian ...

  9. hive表命名规范 源码规则

    tablename 进来前已经把"`","."等过滤掉了,所以就是单词字符喽 \w搞定 \w包含_ 哈哈 规范就是 a-z A-Z 0-9 _ 也就是传说中的单 ...

  10. Redis 常见配置