首页 > 其他分享 >finally中的代码一定会执行吗?

finally中的代码一定会执行吗?

时间:2023-12-24 18:35:30浏览次数:22  
标签:钩子 代码 System try finally 执行

通常在面试中,只要是疑问句一般答案都是“否定”的,因为如果是“确定”和“正常”的,那面试官就没有必要再问了嘛,而今天这道题的答案也是符合这个套路。

1.典型回答

正常运行的情况下,finally 中的代码是一定会执行的,但是,如果遇到以下异常情况,那么 finally 中的代码就不会继续执行了:

  1. 程序在 try 块中遇到 System.exit() 方法,会立即终止程序的执行,这时 finally 块中的代码不会被执行,例如以下代码:
public class FinallyExample {
    public static void main(String[] args) {
        try {
            System.out.println("执行 try 代码.");
            System.exit(0);
        } finally {
            System.out.println("执行 finally 代码.");
        }
    }
}

以上程序的执行结果如下:

finally中的代码一定会执行吗?_System

  1. 在 try 快中遇到 Runtime.getRuntime().halt() 代码,强制终止正在运行的 JVM。与 System.exit()方法不同,此方法不会触发 JVM 关闭序列。因此,当我们调用 halt 方法时,都不会执行关闭钩子或终结器。实现代码如下:
public class FinallyExample {
    public static void main(String[] args) {
        try {
            System.out.println("执行 try 代码.");
            Runtime.getRuntime().halt(0);
        } finally {
            System.out.println("执行 finally 代码.");
        }
    }
}

以上程序的执行结果如下:

finally中的代码一定会执行吗?_面试_02

  1. 程序在 try 块中遇到无限循环或者发生死锁等情况时,程序可能无法正常跳出 try 块,此时 finally 块中的代码也不会被执行。
  2. 掉电问题,程序还没有执行到 finally 就掉电了(停电了),那 finally 中的代码自然也不会执行。
  3. JVM 异常崩溃问题导致程序不能继续执行,那么 finally 的代码也不会执行。

钩子方法解释

在编程中,钩子方法(Hook Method)是一种由父类提供的空或默认实现的方法,子类可以选择性地重写或扩展该方法,以实现特定的行为或定制化逻辑。钩子方法可以在父类中被调用,以提供一种可插拔的方式来影响父类的行为。 钩子方法通常用于框架或模板方法设计模式中。框架提供一个骨架或模板,其中包含一些已经实现的方法及预留的钩子方法。具体的子类可以通过重写钩子方法来插入定制逻辑,从而影响父类方法的实现方式。

2.考点分析

正常运行的情况下,finally 中的代码是一定会执行的,但是,如果遇到 System.exit() 方法或 Runtime.getRuntime().halt() 方法,或者是 try 中发生了死循环、死锁,遇到了掉电、JVM 崩溃等问题,那么 finally 中的代码也是不会执行的。

3.知识扩展

System.exit() 和 Runtime.getRuntime().halt() 都可以用于终止 Java 程序的执行,但它们之间有以下区别:

  1. System.exit():来自 Java.lang.System 类的一个静态方法,它接受一个整数参数作为退出状态码,通常非零值表示异常终止,使用零值表示正常终止。其中,最重要的是使用 exit() 方法,会执行 JVM 关闭钩子或终结器。
  2. Runtime.getRuntime().halt():来自 Runtime 类的一个实例方法,它接受一个整数参数作为退出状态码。其中退出状态码只是表示程序终止的原因,很少在程序终止时使用非零值。而使用 halt() 方法,不会执行 JVM 关闭钩子或终结器。

例如以下代码,使用 exit() 方法会执行 JVM 关闭钩子:

class ExitDemo {
    // 注册退出钩子程序
    static {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("执行 ShutdownHook 方法");
        }));
    }
    public static void main(String[] args) {
        try {
            System.out.println("执行 try 代码。");
            // 使用 System.exit() 退出程序
            System.exit(0);
        } finally {
            System.out.println("执行 finally 代码。");
        }
    }
}

以上程序的执行结果如下:

finally中的代码一定会执行吗?_面试_03

而 halt() 退出的方法,并不会执行 JVM 关闭钩子,示例代码如下:

class ExitDemo {

    // 注册退出钩子程序
    static {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("执行 ShutdownHook 方法");
        }));
    }

    public static void main(String[] args) {
        try {
            System.out.println("执行 try 代码。");
            // 使用 Runtime.getRuntime().halt() 退出程序
            Runtime.getRuntime().halt(0);
        } finally {
            System.out.println("执行 finally 代码。");
        }
    }
}

以上程序的执行结果如下:

finally中的代码一定会执行吗?_Java_04

小结

正常运行的情况下,finally 中的代码是一定会执行的,但是,如果遇到 System.exit() 方法或 Runtime.getRuntime().halt() 方法,或者是 try 中发生了死循环、死锁,遇到了掉电、JVM 崩溃等问题,finally 中的代码是不会执行的。而 exit() 方法会执行 JVM 关闭钩子方法或终结器,但 halt() 方法并不会执行钩子方法或终结器。


标签:钩子,代码,System,try,finally,执行
From: https://blog.51cto.com/vipstone/8956387

相关文章

  • 猜数字首页wxml代码
    <!-- index.wxml --><!-- 定义了三个类名class,primary主要按钮可以使按钮颜色从默认灰色变成绿色 --><view class="container">  <view class="button-container">    <button type="primary" class="button"  bindtap="naviga......
  • vscode+xdebug+phpenv本地调试php代码
    php环境变量先设置环境变量,找到php目录在vscode里安装phpdebug插件点击插件按钮,搜索phpdebug,找到这里标有Xdebug的,点击安装开启Xdebug组件找到对应版本的php去配置php.in文件把这个放到php.ini的最后,如果里面有则根据情况替换即可,端口号要和下面的vscode里面的统一......
  • markdown代码片段
    [插入Snippets][编辑代码片段]快捷键CtrlShiftp,输入SnippetsConfigureUserSnippets然后选择markdown.json在打开的文件中按照提示编辑代码片段[开启编辑器markdown自动补全功能]快捷键CtrlShiftp,输入PreferencesOpenUserSettings,打开配置文件......
  • SAP ABAP 更新函数(Update Function Module)执行出错的原因分析试读版
    本教程前一篇文章,我们已经介绍了SAPABAPUpdateWokeProcess和UpdateFunctionModule的基本概念。129.SAPABAPUpdateProcess(更新进程)的概念和设计动机解析回到笔者知识星球朋友的提问:我们通过一个实战例子来消化前一篇文章学到的理论知识。本教程之前介绍了SA......
  • 代码大全阅读笔记
    c语言中,把常量放在比较的左端,编译器能够检查出错误的使用=符号代码质量特性:正确性,可用性,效率,可靠性,完整性,适应性,精准性,健壮性。可维护性,灵活性,可移植性,可重用性,可读性,可测试性,可理解性。相互联系。多种缺陷检测方法结合,更有利于检测出缺陷。检测发现的缺陷成本远低于测试发现的......
  • Android平台RTMP推送|轻量级RTSP服务能力封装代码实现
    好多开发者问我们,有没有针对Android平台RTMP直播推送、轻量级RTSP服务模块的进一步封装,可以更便捷的调用大牛直播SDK接口。为此,我们分享下我们针对Android平台SmartPublisher做的二次封装代码:packagecom.daniulive.smartpublisher;importandroid.util.Log;importjava.nio.By......
  • 提高代码复用性与可维护性:深入剖析模板方法模式
    什么是模板方法模式模板方法模式是一种行为型设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。在模板方法模式中,抽象类负责给出算法的轮廓和骨架(由一个或多个模板方法组成),而实现类......
  • JavaScript手搓"防抖"优化代码
    一、为什么要防抖就好比我们想象一个场景:当我们在使用我们的页面,我们页面有一个提交数据的按钮!我们每次点击提交按钮,都会向我们的后端服务器发送一个请求!接下来我们来构建一下这样一个简单的页面!<buttonid="submit">提交</button><script>letsub=document.getEle......
  • 代码随想录算法训练营第十一天|20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150
    一、20.有效的括号题目链接:LeetCode20.有效的括号学习前:思路:当前元素为左括号,直接入栈当前元素为右括号,若找到对应的左括号匹配,则循环继续;反之返回false若栈为空,返回true;反之false时间复杂度:O(n)空间复杂度:O(n)学习后:采用入栈右括号,降低复杂度。即当遇到左......
  • 代码堆砌是如何形成的以及如何解决
    量度而行,不失矣。通常来说,我们追求代码清晰性和可维护性,追求代码放置整洁有序,放在它该呆的地方,这样阅读起来逻辑井井有条,自然通畅,节省脑力和精力。代码堆砌,是指只顾实现功能,在原有代码上不断堆砌新的代码,使得整个实现过程逐渐变得杂乱无章。代码堆砌累积足够多后,整个流程会变......