我了解到try catch语句的finally子句总是执行。但有些人告诉我,可以避免执行它(删除它不是一种选择)。
- 有人怎么可能?
- 我很想知道为什么有人想避免执行它?
答案 0 :(得分:6)
使用finally
块中的未捕获异常来杀死它,或者杀死整个JVM(除了其他东西之外杀死线程)。
除了糟糕的设计之外,没有充分的理由停止执行finally
块。如果它不应该每次运行,那么不要将它放在finally
块中。
使用下面的测试代码,我运行两种不同的方案来查看杀死Thread
时会发生什么:
Thread
和sleep
主线程2秒钟。在Thread
内,几乎立即进入finally
块然后再睡5秒钟。主线程完成等待后,使用Thread
终止stop
。Thread
并睡2秒。在Thread
内,在进入finally
区块前5秒钟睡觉,然后在finally
内再睡一会儿,让它有机会被杀死。在第一种情况下,结果是finally
块停止执行。
在第二种情况下,结果是finally
块完全执行,而Thread
上的stop
块执行不少。
输出(注意为所有输出添加的当前线程的名称):
thread-starting [main]
trying [Thread-0]
catching [Thread-0]
finally-sleeping [Thread-0]
thread-stopped [main]
[main]
thread-starting [main]
trying-sleeping [Thread-1]
thread-stopped [main]
finally-sleeping [Thread-1]
finally-done [Thread-1]
代码:
public class Main
{
public static void main(String[] args)
{
testThread(new TestRunnable());
println("");
testThread(new TestRunnable2());
}
private static void testThread(Runnable runnable)
{
Thread testFinally = new Thread(runnable);
println("thread-starting");
testFinally.start();
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
println("main-interrupted...");
}
testFinally.stop();
println("thread-stopped");
}
private static class TestRunnable implements Runnable
{
@Override
public void run()
{
try
{
println("trying");
throw new IllegalStateException("catching");
}
catch (RuntimeException e)
{
println(e.getMessage());
}
finally
{
println("finally-sleeping");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
println("finally-interrupted");
}
println("finally-done");
}
}
}
private static class TestRunnable2 implements Runnable
{
@Override
public void run()
{
try
{
println("trying-sleeping");
Thread.sleep(5000);
}
catch (InterruptedException e)
{
println("trying-interrupted");
}
finally
{
println("finally-sleeping");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
println("finally-interrupted");
}
println("finally-done");
}
}
}
private static void println(String line)
{
System.out.printf("%s [%s]%n", line, Thread.currentThread().getName());
System.out.flush();
}
}
答案 1 :(得分:4)
- 有人怎么可能?
System.exit(0);
- 我很想知道为什么有人想避免执行它?
To answer questions like these and appear smart. ;)
BTW,Thread.stop()不会阻止调用finally
。
Thread t = new Thread() {
@Override
public void run() {
try {
System.out.println("Thread start");
Thread.sleep(1000);
System.out.println("Thread end");
} catch (InterruptedException ie) {
System.out.println("Thread Interrupted");
} catch (Error e) {
System.out.println("Thread threw an error " + e);
throw e;
} finally {
System.out.println("Thread finally");
}
}
};
t.start();
t.join(100);
t.stop();
打印
Thread start
Thread threw an error java.lang.ThreadDeath
Thread finally
答案 2 :(得分:0)
除非发生外部事件,例如Java虚拟机关闭,否则无法避免它。
作为一般规则,您应该始终假设将运行finally块。它的重点是确保它运行而不管try块中发生了什么 - 应该没有理由避免它!
答案 3 :(得分:0)
对于你的第一个问题,我认为我想到的唯一方法就是创造一个无限循环或其他东西。(但它完全没有意义)
try{
while(true);
}
catch(Exception e) {
}
finally {
//..
}
对于你的第二个问题,我真的不知道为什么有人想做那样的事情
答案 4 :(得分:0)
我想不出你想要避免最终阻止的一个好理由。如果你真的不想使用这个功能,那么就不要实现finally块(但需要自担风险)。
杀死JVM会做到这一点,但对于任何生产代码来说,这都不是一个可以接受的解决方案。
为什么删除finally块不是一个选项?