【2021-07-12】当代码执行到 try 语句块时,finally 语句块一定会被执行么?
请移步至:
每日一题 查看更多的题目 ~
答:
不一定。
有两种情况会导致即便代码执行到 try 块,finally 块也有可能不执行:
- 系统终止
- 守护线程被终止
示例程序一:
package com.github.test;
public class Test {
public static void main(String[] args) {
foo();
}
public static void foo() {
try {
System.out.println("In try block...");
System.exit(0);
} finally {
System.out.println("In finally block...");
}
}
}
该程序运行的结果为:
In try block...
原因在于,try 块中,我们使用了 System.exit(0)
方法,该方法会终止当前正在运行的虚拟机,也就是终止了系统,既然系统被终止,自然而然也就执行不到 finally 块的代码了。
示例程序二:
package com.github.test;
public class Test {
public static void main(String[] args) {
Thread thread = new Thread(new Task());
thread.setDaemon(true);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Task implements Runnable {
@Override
public void run() {
try {
System.out.println("In try block...");
Thread.sleep(5000); // 阻塞线程 5 s
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("In finally block");
}
}
}
该程序的输出结果为:
In try block...
Java 的线程可以分为两大类:
- Daemon Thread(守护线程)
- User Thread(用户线程)
所谓的守护线程就是指程序运行的时候,再后台提供一种通用服务的线程,比如垃圾回收线程就是一个守护线程。守护线程并不属于程序中不可或缺的部分,因此,当所有的用户线程结束,程序也就终止,程序终止的同时回杀死进程中所有的守护线程。
上面的实力程序中,main 执行完毕,程序就终止了,所以守护线程也就被杀死,finally 块的代码也就无法执行到了。