在Java中,是否存在最终不会运行的情况?谢谢。
来自Sun中文教程
注意:如果JVM在执行try或catch代码时退出,则finally块可能不会执行。类似地,如果执行try或catch代码的线程被中断或终止,则finally块可能不会执行,尽管整个应用程序仍在运行。
我不知道还有其他方式finally块不会执行...
System.exit 方法关闭虚拟机。
终止当前正在运行的 Java 虚拟机。 参数作为状态码;按照惯例,非零状态码表示异常终止。
此方法调用
Runtime
类中的exit
方法。该方法永远不会正常返回。
try {
System.out.println("hello");
System.exit(0);
}
finally {
System.out.println("bye");
} // try-finally
在上面的代码中,"bye" 没有被输出。
只是为了扩充其他人所说的,任何不会导致类似于JVM退出的情况都将包含在finally块中。因此,以下方法:
public static int Stupid() {
try {
return 0;
}
finally {
return 1;
}
}
它会奇怪地编译并返回1。
与System.exit相关的是,有些灾难性故障可能导致finally块不能执行。如果JVM完全耗尽内存,则可能会直接退出而不会发生catch或finally。
具体来说,我记得有一个项目我们愚蠢地尝试使用
catch (OutOfMemoryError oome) {
// do stuff
}
这没起作用是因为JVM没有足够的内存来执行catch块。
这个帖子错误引用了Sun教程。
注意: 如果JVM在执行try或catch代码时退出,则finally块可能不会执行。同样,如果执行try或catch代码的线程被中断或终止,即使应用程序整体继续运行,finally块也可能不会执行。
如果您仔细查看Sun教程中的finally块,它并没有说“不会执行”,而是“可能不会执行”,这里是正确的描述:
注意: 如果JVM在执行try或catch代码时退出,则finally块可能不会执行。同样,如果执行try或catch代码的线程被中断或杀死,则finally块可能不会执行,尽管应用程序作为一个整体继续运行。
这种行为的显而易见的原因是,在运行时系统线程中处理调用system.exit(),这可能需要一些时间来关闭jvm,同时线程调度程序可以要求执行finally。因此,finally被设计为始终执行,但如果您正在关闭jvm,则有可能在finally得到执行之前关闭jvm。
try { for (;;); } finally { System.err.println("?"); }
在这种情况下,finally
语句将不会执行(除非调用了已弃用的Thread.stop
方法或等效方法,比如通过工具接口调用)。
try { throw new ThreadDeath(); } finally { System.err.println("?"); }
- Tom Hawtin - tackline如果在try
块内发生死锁/活锁,以下是演示它的代码:
public class DeadLocker {
private static class SampleRunnable implements Runnable {
private String threadId;
private Object lock1;
private Object lock2;
public SampleRunnable(String threadId, Object lock1, Object lock2) {
super();
this.threadId = threadId;
this.lock1 = lock1;
this.lock2 = lock2;
}
@Override
public void run() {
try {
synchronized (lock1) {
System.out.println(threadId + " inside lock1");
Thread.sleep(1000);
synchronized (lock2) {
System.out.println(threadId + " inside lock2");
}
}
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
}
public static void main(String[] args) throws Exception {
Object ob1 = new Object();
Object ob2 = new Object();
Thread t1 = new Thread(new SampleRunnable("t1", ob1, ob2));
Thread t2 = new Thread(new SampleRunnable("t2", ob2, ob1));
t1.start();
t2.start();
}
}
这段代码将产生以下输出:
t1 inside lock1
t2 inside lock1
而“最终”从未被打印出来。
public class TestDaemon {
private static Runnable runnable = new Runnable() {
@Override
public void run() {
try {
while (true) {
System.out.println("Is alive");
Thread.sleep(10);
// throw new RuntimeException();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
System.out.println("This will never be executed.");
}
}
};
public static void main(String[] args) throws InterruptedException {
Thread daemon = new Thread(runnable);
daemon.setDaemon(true);
daemon.start();
Thread.sleep(100);
// daemon.stop();
System.out.println("Last non-daemon thread exits.");
}
}
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive
try
块中调用System.exit(0)
时。try
块中出现死锁条件。有两种方法可以停止finally块中的代码执行:
1. 使用System.exit();
2. 如果执行控制不会到达try块。
参见:
public class Main
{
public static void main (String[]args)
{
if(true){
System.out.println("will exceute");
}else{
try{
System.out.println("result = "+5/0);
}catch(ArithmeticException e){
System.out.println("will not exceute");
}finally{
System.out.println("will not exceute");
}
}
}
}