在try或catch块中使用Call return语句或System.exit

7
我在面试中被问到以下问题:
如果在try或catch块上调用返回语句或System.exit,会发生什么?finally块是否会执行?
finally块总是会执行吗?
编辑后,在Java中尝试以上操作:
- 如果我在try块或catch块中放置了返回语句,则finally块会执行 - 如果我从try或catch中调用System.exit,则finally块不会运行
虽然我不知道背后的原因。

1
请检查上面的编辑现在。 - Abhishek Bhatia
1
请参见 http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html,如果 JVM 在 trycatch 块中退出,finally 块将不会运行。 - Nick Meyer
1
请参阅 https://dev59.com/OnA75IYBdhLWcg3wVXav - meriton
3个回答

7
如果在try或catch块中调用return语句或System.exit,会发生什么情况? finally块会执行吗?
对于return语句,是的。如果您想了解详细信息,请参阅JLS section 14.20.2
(请注意,在JLS术语中,return语句被视为“突然终止”。但这并不重要,因为当您仔细分析规范时,您将看到finally块对于正常终止和突然终止都会执行。)
对于System.exit(),不会。调用exit方法永远不会返回,也不会抛出异常。因此,线程的“封闭”finally子句永远不会执行。
(在JLS的术语中,exit()调用根本不会“终止”。它在概念上与进入一个无限循环的方法相同,(神奇地)不使用任何CPU时间。与JVM关闭相关的所有活动都发生在其他线程上。)

3
根据Oracle的教程
注意:如果JVM在执行try或catch代码时退出,则finally块可能不会执行。同样,如果执行try或catch代码的线程被中断或终止,则finally块可能不会执行,尽管整个应用程序仍在运行。
这个声明似乎意味着:
  • 如果调用System.exit(0)(因为当该语句被调用时Java VM退出),finally将不会执行。
  • 如果调用return语句(因为当该语句被调用时Java VM不会退出),finally执行。
您可以使用我快速编写的一些代码来确认此内容:
public class TryExample {
    public static void main(String[] args)
    {
        try {
            int[] i = {1, 2, 3};
            int x = i[3];//Change to 2 to see "return" result
            return;
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("caught");
            System.exit(0);
        } finally {
            System.out.println("finally");
        }
    }
}

在这里,当在try块中调用return时,“finally”仍会输出到终端,但是当在catch块中调用System.exit(0)时,它不会输出。

@StephenC 编辑后,将链接仅称为“教程”,而不是“官方文档”。 - Nick Meyer

2

不会,当try-catch块没有正常完成时,finally块不会被执行。

这里是JLS,它说明了这一点:

If execution of the try block completes normally, then the finally block is executed

相同的方法适用于catch块
 If the catch block completes normally, then the finally block is executed.

由于您在try块中调用了终止程序的System.exit,因此try-catch不会正常完成,因此finally块不会被执行。

对于return语句,try-catch会正常完成,因为您没有阻止try块(例如无限循环,线程休眠,终止程序等),因此在从方法返回后执行finally块


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接