Java中的finally一定会被执行吗

简介: 在Java中,`finally`块通常会在正常情况下执行,但在特定异常情况下(如调用`System.exit()`、`Runtime.getRuntime().halt()`、死锁、掉电或JVM崩溃)则不会执行。此外,`System.exit()`会触发JVM关闭钩子,而`Runtime.getRuntime().halt()`则不会。面试时遇到疑问句,答案往往是“否定”的,符合这一逻辑。

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

1.典型回答

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

  1. 程序在 try 块中遇到 System.exit() 方法,会立即终止程序的执行,这时 finally 块中的代码不会被执行,例如以下代码:

java

代码解读

复制代码

public class FinallyExample {
    public static void main(String[] args) {
        try {
            System.out.println("执行 try 代码.");
            System.exit(0);
        } finally {
            System.out.println("执行 finally 代码.");
        }
    }
}

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

  1. 在 try 快中遇到 Runtime.getRuntime().halt() 代码,强制终止正在运行的 JVM。与 System.exit()方法不同,此方法不会触发 JVM 关闭序列。因此,当我们调用 halt 方法时,都不会执行关闭钩子或终结器。实现代码如下:

java

代码解读

复制代码

public class FinallyExample {
    public static void main(String[] args) {
        try {
            System.out.println("执行 try 代码.");
            Runtime.getRuntime().halt(0);
        } finally {
            System.out.println("执行 finally 代码.");
        }
    }
}

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

  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 关闭钩子:

java

代码解读

复制代码

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 代码。");
        }
    }
}

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

java

代码解读

复制代码

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


转载来源:https://juejin.cn/post/7313501001788604450

相关文章
|
10月前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
230 2
【JAVA】final、finally、finalize 有什么区别?
【JAVA】final、finally、finalize 有什么区别?
|
11月前
|
缓存 安全 Java
Java中 final、finally、finalize 有什么区别?
本文详细阐述了Java中`final`、`finally`和`finalize`的区别:`final`用于修饰类、方法和变量以表示不可变性;`finally`是用于确保在`try-catch`结构中无论是否发生异常都能执行的代码块;而`finalize`是`Object`类的方法,用于在对象被垃圾回收前执行清理工作,但在JDK 9中已被标记为弃用。
270 0
Java中 final、finally、finalize 有什么区别?
【Java基础面试三十九】、 finally是无条件执行的吗?
这篇文章解释了Java中的finally块的特性,即无论是否发生异常或执行了return语句,finally块都会无条件执行,除非使用System.exit()退出虚拟机。
【Java基础面试四十】、在finally中return会发生什么?
文章讨论了在Java中finally块中使用return语句的问题,指出如果在finally块中使用return或throw语句,将导致try块或catch块中的相应语句失效,因为finally块中的return或throw会终止方法,之后系统不会再执行try或catch块中的代码。
|
Java
面试官:小伙子来说一说Java中final关键字,以及它和finally、finalize()有什么区别?
面试官:“小伙子,用过final关键字吗?” 我:“必须用过呀” 面试官:“好,那来说一说你对这个关键字的理解吧,再说一说它与finally、finalize()的区别” 我:“好嘞!
91 1
|
监控 Java 程序员
详解Java中的异常体系结构(throw,throws,try-catch,finally,自定义异常)
详解Java中的异常体系结构(throw,throws,try-catch,finally,自定义异常)
299 0
|
Java 数据库连接
【零基础学Java】—finally代码块(四十七)
【零基础学Java】—finally代码块(四十七)
Java 最常见的面试题:final、finally、finalize 有什么区别?
Java 最常见的面试题:final、finally、finalize 有什么区别?
Java 最常见的面试题:try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
Java 最常见的面试题:try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

热门文章

最新文章