据我所知,以下两个代码片段都将用于相同的目的。为什么有finally
块?
代码 A:
try { /* Some code */ }
catch { /* Exception handling code */ }
finally { /* Cleanup code */ }
代码 B:
try { /* Some code */ }
catch { /* Exception handling code */ }
// Cleanup code
Throwable
......)一个finally
块确保无论您退出该块(以几种显式中止整个过程的方式为模),它都会被执行。这对于资源的确定性清理很重要。
请注意(至少在 Java 中,也可能在 C# 中)也可以有一个try
没有 a 的块catch
,但有一个finally
. 当块中发生异常时,try
块中的代码在finally
异常被向上抛出之前运行:
InputStream in = new FileInputStream("somefile.xyz");
try {
somethingThatMightThrowAnException();
}
finally {
// cleanup here
in.close();
}
无论您的 try 或 catch 块中发生了什么,您可能都希望放置您想要执行的代码。
此外,如果您使用多个 catch 并且如果您想放置一些对于所有 catch 块都通用的代码,这将是一个放置的地方 - 但您不能确定 try 中的整个代码是否已执行。
例如:
conn c1 = new connection();
try {
c1.dosomething();
} catch (ExceptionA exa) {
handleexA();
//c1.close();
} catch (ExceptionB exb) {
handleexB();
//c1.close();
} finally {
c1.close();
}
finally 总是被执行,而你的代码在 catch 之后可能不会。
即使我们的应用程序被强制关闭,也会有一些我们必须执行的任务(如内存释放、关闭数据库、释放锁等),如果您在finally
块中编写这些代码行,无论是否抛出异常,它都会执行不是...
你的应用程序可能是线程的集合,Exception
终止线程而不是整个应用程序,在这种情况下finally
更有用。
在某些情况下finally
不会执行,例如 JVM Fail、Thread terminate 等。
因为无论可能引发任何异常,您都需要执行该代码。例如,您可能需要清理一些非托管资源('using' 构造编译为 try/finally 块)。
还在向下滚动?干得好!
这个问题给了我一段时间的艰难时光。
try
{
int a=1;
int b=0;
int c=a/b;
}
catch(Exception ex)
{
console.writeline(ex.Message);
}
finally
{
console.writeline("Finally block");
}
console.writeline("After finally");
在上述情况下会打印什么?是的,没猜错:
ex.Message——不管它是什么(可能试图除以零)
最后阻塞
终于之后
try
{
int a=1;
int b=0;
int c=a/b;
}
catch(Exception ex)
{
throw(ex);
}
finally
{
console.writeline("Finally block");
}
console.writeline("After finally");
这会打印什么?没有什么!由于 catch 块引发错误,因此引发错误。
在一个良好的编程结构中,您的异常将被汇集,从某种意义上说,此代码将从另一层处理。为了刺激这种情况,我将嵌套尝试此代码。
try
{
try
{
int a=1;
int b=0;
int c=a/b;
}
catch(Exception ex)
{
throw(ex);
}
finally
{
console.writeline("Finally block")
}
console.writeline("After finally");
}
catch(Exception ex)
{
console.writeline(ex.Message);
}
在这种情况下,输出将是:
很明显,当您捕获异常并将其再次抛出到其他层(Funneling)时,抛出后的代码不会被执行。它的作用类似于函数内部的 return 工作方式。
您现在知道为什么不在 catch 块之后关闭代码上的资源了。将它们放在 finally 块中。
finally
总是执行,除非 JVM 被关闭,finally
只是提供一种方法将清理代码放在一个地方。
如果您必须将清理代码放在每个catch
块中,那就太乏味了。
有时您可能无论如何都想执行一段代码。是否抛出异常。然后一个使用finally
.
java中的finally块可用于放置“清理”代码,例如关闭文件、关闭连接等。
如果程序退出(通过调用 System.exit() 或通过导致导致进程中止的致命错误),将不会执行 finally 块。
如果 catch 块抛出任何异常,那么剩余的代码将不会执行,因此我们必须编写 finaly 块。