Java异常系列之finally的真正运行时机

栏目: Java · 发布时间: 4年前

内容简介:异常是Java核心中非常重要的一个概念,但却很容易被大家忽略,这个系列我们会深入讲一下这个话题。学完这个系列,相信会让你对异常体系以及异常的各种使用场景,了如指掌,成为你职业进阶的必备技能。在之前的但 try-with-resources 语句仅仅适用于自动关闭资源,有些场景下我们需要无论一段代码发生异常与否,都需要执行另外一段代码,这个时候就需要使用 finally 块了。

异常是 Java 核心中非常重要的一个概念,但却很容易被大家忽略,这个系列我们会深入讲一下这个话题。学完这个系列,相信会让你对异常体系以及异常的各种使用场景,了如指掌,成为你职业进阶的必备技能。

名称 状态
finally 的真正运行时机 已完成
try-with-resources 语句 已完成
Java 异常体系 创作中...
catch 中的异常参数 创作中...
Java 异常链 创作中...
SpringMVC 中的异常处理 创作中...
自定义 SpringMVC 的异常处理链 创作中...

在之前的 Java语法糖 : 使用 try-with-resources 语句安全地释放资源 一文中,我们介绍了如何通过 try-with-resources 语句来代替丑陋的 finally 块。

但 try-with-resources 语句仅仅适用于自动关闭资源,有些场景下我们需要无论一段代码发生异常与否,都需要执行另外一段代码,这个时候就需要使用 finally 块了。

如果有人问你 发生异常以后 finally 块的内容什么时候会执行?你也许会毫不犹豫地回答:当然是执行完 catch 块的内容以后执行了。

但有时候你的回答也许没法这么干脆,比如下面这个例子。

当在 catch 块和 finally 块同时 return 的时候,到底会 return 什么呢?

public static int testFinally1() {
    try {
        Integer.parseInt("exception here");
    } catch (Exception e) {
        System.out.println("catch block 1");
        return 11;
    } finally {
        System.out.println("finally block 1");
        return 12;
    }
}
复制代码

事实上,即使 catch 块有 return 语句, finally 块必然执行的逻辑还是成立的。上面的方法, return 的是 12 。先输出 catch block 1 ,然后输出 finally block 1 ,最后返回 12

不知道你发现规律没有,下面再举个例子你就更清晰了。

public static int testFinally3() {
    try {
        System.out.println("start");
        Integer.parseInt("testFinally3");
        System.out.println("never run");
    } catch (Exception e) {
        System.out.println("catch block 3");
        return iamReturn();
    } finally {
        System.out.println("finally block 3");
    }
    return 31;
}

public static int iamReturn() {
    System.out.println("return block");
    return 666;
}
复制代码

思考一下执行这个方法会分别输出和返回什么?

先别着急看答案,根据我们之前发现的规律, finally 块必然执行,而 catch 块的非 return 部分需要在 finally 块之前执行。那么最终返回的应该是 666

答案确实如此。下面是控制台输出的顺序:

start
catch block 3
return block
finally block 3
复制代码

由此,我们可以总结 finally 块的真正运行时机了:

  1. finally 块必然执行,不论发生异常与否,也不论在 finally 之前是否有 return
  2. 不管在 try 块中还是在 catch 块中包含 return,finally 块总是在 return 之前执行。
  3. 如果 finally 块中有 return ,那么 try 块和 catch 块中的 return 就没有执行机会了。

如果你真的理解了finally 块的真正运行时机,那么请思考一下,下面程序的返回值是 21 还是 22 ,欢迎留言讨论。

public static int testFinally2() {
    try {
        System.out.println("start");
        return 21;
    } catch (Exception e) {
        System.out.println("catch block 2");
    } finally {
        System.out.println("finally block 2");
    }
    return 22;
}
复制代码
Java异常系列之finally的真正运行时机

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人月神话

人月神话

[美] 弗雷德里克·布鲁克斯 / 汪颖 / 清华大学出版社 / 2002-11 / 29.80元

作者为人们管理复杂项目提供了颇具洞察力的见解,既有很多发人深省的观点,也有大量的软件工程实践。书中的内容来自布鲁克斯在IBM公司System 360家族和OS 360中的项目管理经验。初版的20年后,布鲁克斯重新审视了他原先的观点,增加了一些新的想法和建议。新增加的章节包括:原著中一些核心观点的精华;在经过了一个时代以后,Brooks博士对原先观点新的认识;1986年的经典文章《没有银弹》;对19......一起来看看 《人月神话》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换