我已经使用了多种语言的try-catch / except-finally变种多年,今天有人问我最后的意思是什么,我无法回答。
基本上你为什么要在finally中放入一个语句而不是仅仅将它放在整个try-catch块之后?或者换句话说,以下代码块之间存在差异:
try{ //a}
catch {//b}
finally {//c}
try{//a}
catch{//b}
//c
编辑:
人们,我知道最后会做什么,我已经使用了很长时间,但我的问题是在上面的例子中,将//c
放在最后似乎是多余的,不是吗?
答案 0 :(得分:82)
finally
块的目的是确保代码在三种情况下运行,而这些情况不会仅仅使用“catch”块来处理:
可以在finally
之前复制return
代码或抛出,并在自己的try / catch中包装catch
块以允许发生意外异常的可能性,但它是更容易放弃所有这些,只需使用finally
块。
exception
块的finally
参数,以处理在异常后需要清理但仍希望它的情况渗透调用堆栈(例如,可以在这样的构造中包装构造函数的代码,并且Dispose
正在构造的对象(如果构造函数将以异常退出)。
答案 1 :(得分:2)
即使在try块中抛出异常,也会执行最后一个块。因此,例如,如果您之前打开了一个流,则可能需要关闭该流,否则抛出异常。最后块对于这样的问题很有用。
答案 2 :(得分:0)
Finally
即使您遇到异常,也要确保您的代码已执行。
finally块对于清理try块中分配的任何资源以及运行任何必须执行的代码(即使存在异常)非常有用
http://msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.80).aspx
答案 3 :(得分:0)
finally
是一种语法糖,允许以try-catch
模式使用DRY原理。如果库代码没有足够的信息来处理某些状态,并且希望客户端代码解决它,通常会引发异常。如果没有库与客户端的代码分离,则可以使用if
而不是try
处理所有内容。
让我们看看没有finally
的标准情况:
void myFunction() {
var r = allocateResources();
r.doSomething();
if(somethingBadHappens) {
freeResources(r);
throw new Exception(CODE42);
}
r.doSomethingMore();
freeResources(r);
}
在上面的代码段中,您重复freeResources()
:这可以是您需要重复的多个语句。这闻起来很香,finally
块是干净代码的解决方案:
void myFunction() {
var r = allocateResources();
try {
r.doSomething();
if(somethingBadHappens) throw new Exception(CODE42);
r.doSomethingMore();
}
finally {
freeResources(r);
}
happyFunction();
}
让我们实现三个抽象级别:
allocateResources()
功能的库代码myFunction
的代码,消耗了A1 myFunction
的客户端代码:function A3code() {
try {
myFunction();
doSomething();
}
catch(Exception e) {
// no hanging resources here
Console.WriteLine(e);
}
}
现在让我们看看会发生什么:
allocateResources()
抛出A1,我们不知道如何在A2中处理它(A2代码可以在没有控制台的环境中运行),因此我们将情况推迟到A3,而无需添加任何其他代码。 如果在此处引发Exception,则不会执行finally块,因为finally
已绑定到未输入的try
。somethingBadHappens
在try块中,则堆栈会退回到A3,并在执行finally
块之前先处理情况但是,因此我们无需重复如果没有例外发生的话。finally
之前,我们可以添加catch
块,并尝试解决A1的一些潜在异常,这些异常可能在调用r.doSomething
方法中出现。通常,我们希望尽快处理异常,以使客户端代码(A3)对于客户端编码人员而言更为舒适。happyFunction()
仅在myFunction()
中(try
块的内部或外部)没有抛出任何异常时执行。
正如@supercat指出的那样,如果finally
块通过return退出,则try
块也会执行。我建议您避免这种不良习惯,并且在每个函数中只有一个返回值(也许在函数的开始处就存在一些早期)。单次返回功能的原因是:
多次返回的原因是避免了许多嵌套的if,但是还有其他解决方法。 Exception
是此规则的例外。