除去语法,两者之间有什么区别?
try {
}
catch() {
}
finally {
x = 3;
}
andtry {
}
catch() {
}
x = 3;
编辑:在.NET 2.0中吗?所以
try {
throw something maybe
x = 3
}
catch (...) {
x = 3
}
行为等效吗?
除去语法,两者之间有什么区别?
try {
}
catch() {
}
finally {
x = 3;
}
andtry {
}
catch() {
}
x = 3;
编辑:在.NET 2.0中吗?所以
try {
throw something maybe
x = 3
}
catch (...) {
x = 3
}
行为等效吗?
首先,如果在try块内使用RETURN语句,则finally块仍会执行,但位于try-catch-finally块下方的代码将不会被执行。
根据语言的不同,可能会存在一些细微的语义差别,但大致意思是当代码块中出现异常时,finally块将(几乎)总是被执行。
在第二个示例中,如果catch块中的代码返回或退出,则x = 3不会被执行。而在第一个示例中,它会被执行。
在.NET平台上,有些情况下finally块的执行不会发生: 安全性异常、线程挂起、计算机关闭等。
在Java中:
无论异常是否被正确捕获于catch()中,或者你根本没有用catch语句,finally块都会被调用。
try catch finally 是非常重要的结构。你可以确信,即使抛出异常,finally块中的代码也会被执行。这在处理外部资源以释放它们方面非常重要。垃圾回收并不会为您完成此操作。在finally部分中,您不应该有return语句或抛出异常。虽然可能做到这一点,但这是一个不好的实践,并可能导致不可预测的结果。
如果您尝试这个例子:
try {
return 0;
} finally {
return 2;
}
finally块之所以有用,原因如下:
这些特点使得finally块非常适合用于关闭文件句柄或套接字。
finally块与try/catch在同一作用域内,因此您将可以访问在其中定义的所有变量。
假设您有一个文件处理程序,这是编写方式的不同之处。
try
{
StreamReader stream = new StreamReader("foo.bar");
stream.write("foo");
}
catch(Exception e) { } // ignore for now
finally
{
stream.close();
}
StreamReader stream = null;
try
{
stream = new StreamReader("foo.bar");
stream.write("foo");
} catch(Exception e) {} // ignore
if (stream != null)
stream.close();
请记住,任何在finally块中的代码都不能保证一定会执行。想象一下,如果出现了中断信号、Windows崩溃或者电源故障等情况,那么finally块中的代码就无法执行了。因此,在关键业务代码中依赖finally是不可取的。
最终块允许您作为开发人员在try{}块中遇到错误的前置代码的操作后,无论如何都可以整理自己的代码,正如其他人指出的那样,这主要涉及释放资源-关闭指针/套接字/结果集,将连接返回到池中等。
@mats非常正确,总会存在“硬”故障的潜在可能性-finally块不应包含关键任务代码,这些代码应始终在try{}内部以事务方式完成
@mats再次强调-真正美妙之处在于它允许您将异常抛回到自己的方法中,并仍然保证您的代码整洁:
try
{
StreamReader stream = new StreamReader("foo.bar");
mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
//Swallow this
logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
//More serious, throw this one back
throw(e);
}
finally
{
stream.close();
}
@iAn 和 @mats:
我不会在 finally {} 中“拆除”在 try {} 中“设置”的任何内容。最好将流的创建移到 try {} 之外。如果需要处理流创建时的异常,可以在更大的范围内完成。
StreamReader stream = new StreamReader("foo.bar");
try {
mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
//Swallow this
logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
//More serious, throw this one back
throw(e);
}
finally {
stream.close();
}
throw(e); //rewrites stack trace
与 throw; //re-throws the original exception
是不同的。 - vitule我真的认为finally
没有好处,这可能是为什么它直到“最近”才出现在编程语言中的原因。大多数例子说明stream.close()
可能会导致空引用异常,因此您仍然必须测试它是否为空。
是的,如果你在try{}
中返回,finally
仍然运行。但这是好的做法吗?这似乎像是心理上的体操,还不如把goto
带回来。为什么不等待,在块之后返回?所有finally {}
所做的就是给你的代码添加两三行。