服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java语言中finally是否一定会执行你知道吗

Java语言中finally是否一定会执行你知道吗

2022-07-20 13:00小夏陌 Java教程

这篇文章主要为大家详细介绍了Java finally是否一定会执行,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

简介

我们都知道,finally 作为异常处理的一部分,它只能紧跟在try/catch语句后,附带一个语句块,表示这段语句,“在正常情况下”,最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。那么在我们的应用在运行中,一定会运行finally代码块吗?其实不是的,有以下几种情况我们的finally代码块是不会运行的。

finally 代码块不会运行的情况

情况一:代码流程并未进入try语句块

这也是最好理解的情况,如果代码流程不进入try代码块,则相应的catch和finally代码块自然不会执行。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
    int i = 0;
    System.out.println("enter main block");
    boolean flag = false;
    if (flag) {
        try {
            System.out.println("enter try block");
            i = i / i;
        } catch (Exception e) {
            System.out.println("enter catch block");
        }finally {
            System.out.println("enter finally block");
        }
    }
}

运行结果为:

enter main block

情况二: 使用了 System.exit(int) 退出程序

在进入try或catch块后,使用了 System.exit(int) 退出程序。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) {
    int i = 0;
    System.out.println("enter main block");
    try {
        System.out.println("enter try block");
        System.exit(0);
        i = i / i;
    } catch (Exception e) {
        System.out.println("enter catch block");
    } finally {
        System.out.println("enter finally block");
    }
}

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) {
        int i = 0;
        System.out.println("enter main block");
        try {
            System.out.println("enter try block");
            i = i / i;
        } catch (Exception e) {
            System.exit(0);
            System.out.println("enter catch block");
        } finally {
            System.out.println("enter finally block");
        }
    }

运行结果为:

enter main block
enter try block

但是呢,如果 System.exit(int) 在try代码块异常语句之后, finally 还是会被执行,因为已经没有机会执行 System.exit(int) ,程序已经退出了,比如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) {
    int i = 0;
    System.out.println("enter main block");
    try {
        System.out.println("enter try block");
        i = i / i;
        System.exit(0);
    } catch (Exception e) {
        System.out.println("enter catch block");
    } finally {
        System.out.println("enter finally block");
    }
}

运行结果为:

enter main block
enter try block
enter catch block
enter finally block

情况三:程序所在的线程死亡

在当前线程死亡的情况下,finally里的语句也不会执行,比如干扰中断,或者程序外部kill该线程,或者是意外中止。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
    int i = 0;
    System.out.println("enter main block");
    try {
        System.out.println("enter try block");
        // 模拟执行任务10s,然后在执行任务过程中杀死该线程
        Thread.sleep(10 * 1000);
        i = i / i;
    } catch (Exception e) {
        System.out.println("enter catch block");
    } finally {
        System.out.println("enter finally block");
    }
}

这里在休眠里,用kill命令,杀死该线程,模拟非正常退出,最后运行结果为:

enter main block
enter try block

这里值得注意的是,我们常常在try语句块里获取了一些临界资源,然后finally语句块里释放该资源。此时,如果正常获得取资源后,程序非正常中断,则我们并未正常释放该资源,就会导致资源可能会被无限占用,所以这里要考虑一下其它的解决方法,比如给资源设置一个使用时间等,到期自动收回。

情况四:其它非正常退出

还有其它非正常退出(道理同上,就不演示了),也会导致finally代码块不执行,比如物理关闭电源,关闭 CPU等。这些其实在开发生产环境中是常有出现的,比如在开发中,某一台服务器获取锁后,不小心断电或宕机了(未成功释放锁),然后导致别的机器也不能获得到锁(如果锁无时间限制),最终导致出现系统型的问题。完事以后,你们开发也不知道发生了什么事,就把所有服务都重启了一次,解决了问题,最后说一句:“啊!还是重启大法好”。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容! 

原文链接:https://blog.csdn.net/qq_22136439/article/details/123028976

延伸 · 阅读

精彩推荐
  • Java教程Java中Boolean与字符串或者数字1和0的转换实例

    Java中Boolean与字符串或者数字1和0的转换实例

    下面小编就为大家带来一篇Java中Boolean与字符串或者数字1和0的转换实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看...

    Java教程网4282020-11-30
  • Java教程java设计模式之装饰模式详细介绍

    java设计模式之装饰模式详细介绍

    这篇文章主要介绍了java设计模式之装饰模式,有需要的朋友可以参考一下 ...

    java教程网4312019-10-26
  • Java教程详解Java中Iterable与Iterator用法

    详解Java中Iterable与Iterator用法

    在本文中小编给大家分享了关于Java中Iterable与Iterator的用法知识点内容,有兴趣的朋友们可以学习下。...

    Java教程网12222021-06-03
  • Java教程java实现线性表及其算法

    java实现线性表及其算法

    线性表是最简单和最常用的一种数据结构,它是有n个体数据元素(节点)组成的有限序列,这篇文章主要介绍了java实现线性表及其算法,小编觉得挺不错...

    博弈5642021-05-06
  • Java教程Java线程的生命周期的详解

    Java线程的生命周期的详解

    这篇文章主要介绍了Java线程的生命周期的详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下...

    资深架构师5662021-01-27
  • Java教程Java编程Post数据请求和接收代码详解

    Java编程Post数据请求和接收代码详解

    这篇文章主要介绍了Java编程Post数据请求和接收代码详解,涉及enctype的三种编码,post与get等相关内容,具有一定参考价值,需要的朋友可以了解下。...

    白天的猫头鹰8042021-02-07
  • Java教程Java中Lambda表达式的使用详解

    Java中Lambda表达式的使用详解

    Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达...

    四季人063792022-01-25
  • Java教程在IDEA中maven配置MyBatis的流程详解

    在IDEA中maven配置MyBatis的流程详解

    刚学完javaweb,对自己的Dao层代码很不满意的话,可得来学学MyBatis.学习MyBatis既可以改进JDBC的使用,实现Dao层也会变得很简便,下面我将介绍IDEA中maven配置MyBati...

    我永远喜欢迪卢克9882021-09-18