无论finally块中的内容是什么,它总是被执行(几乎),那么将代码封闭到它或不封闭它之间有什么区别呢?


当前回答

最后,如:

try {
  // do something risky
} catch (Exception ex) {
  // handle an exception
} finally {
  // do any required cleanup
}

是try. catch块之后执行代码的保证机会,而不管try块是否抛出异常。

这使得它非常适合于释放资源、db连接、文件句柄等。

其他回答

有时您不想处理异常(没有catch块),但希望执行一些清理代码。

例如:

try
{
    // exception (or not)
}
finally
{
    // clean up always
}

使用try-finally的大多数优点已经指出了,但我想再加上这一点:

try
{
    // Code here that might throw an exception...

    if (arbitraryCondition)
    {
        return true;
    }

    // Code here that might throw an exception...
}
finally
{
    // Code here gets executed regardless of whether "return true;" was called within the try block (i.e. regardless of the value of arbitraryCondition).
}

这种行为使它在各种情况下都非常有用,特别是当您需要执行清理(处置资源)时,尽管在这种情况下使用块通常更好。

Finally块的控制流在Try块或Catch块之后。

[1. First Code]
[2. Try]
[3. Catch]
[4. Finally]
[5. After Code]

除了 1 > 2 > 3 > 4 > if 3有Return语句 1 > 2 > 3 >

没有例外 1 > 2 > 4 > 如果2有一个返回语句 1 > 2 >

任何时候你使用非托管代码请求,如流读取器,db请求等;你想要捕获异常,然后使用try catch finally并在finally中关闭流,数据读取器等,如果你不这样做,当它出错时连接不会被关闭,这对db请求来说真的很糟糕

 SqlConnection myConn = new SqlConnection("Connectionstring");
        try
        {
            myConn.Open();
            //make na DB Request                
        }
        catch (Exception DBException)
        {
            //do somehting with exception
        }
        finally
        {
           myConn.Close();
           myConn.Dispose();
        }

如果您不想捕获错误,请使用

 using (SqlConnection myConn = new SqlConnection("Connectionstring"))
        {
            myConn.Open();
            //make na DB Request
            myConn.Close();
        }

如果有错误,连接对象将被自动处理,但您没有捕获错误

如文档中所述:

catch和finally的一个常见用法是在try块中获取和使用资源,在catch块中处理异常情况,并在finally块中释放资源。

同样值得一读的是:

一旦找到匹配的catch子句,系统就准备将控制转移到catch子句的第一个语句。在catch子句开始执行之前,系统首先按顺序执行所有与try语句关联的finally子句,这些语句的嵌套比捕获异常的语句嵌套多。

因此很明显,即使前面的catch子句有return语句,驻留在finally子句中的代码也将被执行。