考虑到这段代码,我能绝对确定finally块总是执行的吗,不管something()是什么?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("I don't know if this will get printed out");
}
考虑到这段代码,我能绝对确定finally块总是执行的吗,不管something()是什么?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("I don't know if this will get printed out");
}
当前回答
最后总是在结尾处调用
当您尝试时,它会执行一些代码,如果在尝试中发生了什么,那么catch将捕获该异常,您可以打印一些mssg或抛出错误,然后最后执行块。
Finally通常在执行清理时使用,例如,如果使用java中的扫描仪,则可能应该关闭扫描仪,因为它会导致其他问题,例如无法打开某些文件
其他回答
公认的答案在几乎所有方面都是正确的,但它仍然只是事实的一半(好吧,95%的事实)。
假设以下代码:
private final Lock m_Lock = new ReentrantLock();
…
public final SomeObject doSomething( final SomeObject arg )
{
final SomeObject retValue;
try
{
lock.lock();
retValue = SomeObject( arg );
}
finally
{
out.println( "Entering finally block");
callingAnotherMethod( arg, retValue );
lock.unlock();
}
return retValue;
}
…
try
{
final var result = doSomething( new SomeObject() );
}
catch( final StackOverflowError e ) { /* Deliberately ignored */ }
调用doSomething()方法将几乎立即导致StackOverflowError。
锁也不会松开!
但是,当finally块总是被执行时(接受的答案中已经列出了例外情况),这怎么会发生呢?
这是因为不能保证finally块中的所有语句都真正执行!
如果在调用lock.unlock()之前调用System.exit()或throws语句,这将是显而易见的。
但示例代码中没有类似的内容…
除此之外,调用lock.unlock()之前finally块中的另外两个方法调用将导致另一个StackOverflowError…
瞧,锁没有松开!
虽然这样的示例代码很愚蠢,但在许多类型的软件中都可以找到类似的模式。只要最后一个街区没有发生什么丑恶的事情,一切都会好起来的…
有趣的事实是,它在Java的更高版本中不起作用(这意味着在更高的版本中,锁被释放了…)。不知道何时以及为什么会发生变化。
但您仍然必须确保finally块始终正常终止,否则它是否始终被执行可能无关紧要…
简而言之,在官方Java文档(单击此处)中-
如果JVM在执行try或catch代码时退出,则finally块可能不执行。同样,如果线程执行try-or-catch代码被中断或终止,finally块可能即使应用程序作为一个整体继续,也不会执行。
是的,finally将在执行try或catch代码块后调用。
唯一不会被调用的时间是:
如果调用System.exit()如果调用Runtime.getRuntime().hart(exitStatus)如果JVM首先崩溃如果JVM到达try或catch块中的无限循环(或其他一些不可中断、不终止的语句)如果操作系统强制终止JVM进程;例如,在UNIX上,kill-9<pid>如果主机系统失效;例如,电源故障、硬件错误、操作系统死机等如果finally块将由守护程序线程执行,并且所有其他非守护程序线程在finally调用之前退出
此外,虽然这是一种糟糕的做法,但如果finally块中有一个return语句,它将胜过常规块中的任何其他返回。也就是说,以下块将返回false:
try { return true; } finally { return false; }
从finally块抛出异常也是一样的。
是的,会的。无论try或catch块中发生什么,除非调用System.exit()或JVM崩溃。如果块中有任何return语句,finally将在该return语句之前执行。