我在面试中被问到以下问题:
如果调用return语句或System。尝试退出或者接球块?最终会阻塞执行吗?
finally块总是被执行吗?
编辑:在java中尝试以上操作后:
finally
块执行如果我把返回语句放在try块或catch块,但是finally
块不运行,如果我调用系统。
我不明白背后的原因。
如果调用return语句或System。尝试退出或者接球块?
将最终阻塞执行?
如果是return
,则为Yes。如果需要详细信息,可以在JLS第14.20.2节中指定。
(注意,在JLS术语中,return
被视为突然终止。但这并不重要,因为当您仔细分析规范时,您将看到finally
在正常和突然终止时都被执行。
在System.exit()
的情况下,No。对exit
方法的调用永远不会返回,也不会抛出异常。因此,线程的"封闭"finally
子句永远不会被执行。
(用JLS的说法,exit()
调用根本不会"终止"。从概念上讲,它与进入无限循环的方法相同,(神奇地)不使用任何CPU时间。与JVM关闭相关的所有活动都发生在其他线程上。
根据Oracle的教程:
注意:如果JVM在执行try或catch代码时退出,则finally块可能不会执行。同样,如果线程执行try或者catch代码被中断或终止,finally块可能不会执行即使应用程序作为一个整体继续。
这句话似乎暗示:
- 如果调用
System.exit(0)
,finally
块将不执行 (因为Java VM在调用该语句时退出) - it 将在调用
return
语句时执行 (因为调用该语句时Java VM不退出)。
你可以用我很快写的一些代码来确认这一点:
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)
时,它不是。
不,当try-catch没有正常完成时,finally block不会被执行。
这是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.
由于你正在调用System.exit
,它在try block
中终止程序,因此try-catch不能正常完成,因此finally block
不会被执行。
对于return statement
, try-catch不会正常完成,因为您没有阻塞try block
(例如无限循环,休眠线程,终止程序等),因此finally block
在您从方法返回后执行。