最终阻止的目的是什么?

时间:2020-03-05 18:49:38  来源:igfitidea点击:

除了语法,两者之间有什么区别

try {
}
catch() {
}
finally {
    x = 3;
}

try {
}
catch() {
}

x = 3;

编辑:.NET 2.0中?

所以

try {
    throw something maybe
    x = 3
}
catch (...) {
    x = 3
}

在行为上是等效的?

解决方案

回答

因此,我们可以清理在try块中初始化的所有打开的连接等。如果我们打开了一个连接,然后发生了异常,则该异常将无法正确关闭。这种类型的情况就是finally块的用途。

回答

在Java中:

无论是否在catch()中正确捕获了异常,或者实际上是否有捕获,最终总是被调用。

回答

取决于语言,因为语义上可能会有一些细微的差异,但是想法是,即使try块中的代码引发了异常,它也将(几乎)始终执行。

在第二个示例中,如果catch块中的代码返回或者退出,则x = 3将不会执行。首先,它将。

在.NET平台中,某些情况下将不会执行finally块:
安全异常,线程挂起,计算机关闭:)等。

回答

好吧,一方面,如果我们在try块中返回,则finally仍将运行,但是try-catch-finally块下面列出的代码将不会运行。

回答

无论我们是否捕获到异常,都应该执行finally块。
请参阅尝试/捕获/最终示例

回答

在尝试和捕获为空的情况下,没有区别。否则,我们可以确定将执行finally。

例如,如果我们在catch块(重新抛出)中抛出一个新的Exception,则仅当该赋值位于finally块中时才会执行该赋值。

通常,final用于自己清理(关闭DB连接,文件句柄等)。

最后,我们永远不要使用控制语句(返回,中断,继续),因为这可能是维护的噩梦,因此被认为是不好的做法

回答

即使抛出异常或者到达return语句(尽管可能与语言有关),也会始终调用finally块(不是很总是...)。这是一种清理方法,我们知道它将始终被调用。

回答

@Ed,我们可能会想到类似catch(...)这样的东西,它会捕获C ++中未指定的异常。

但是finally是无论catch块中发生什么都将被执行的代码。

Microsoft最终会在C#上提供帮助页面

回答

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中的所有代码都将在偶数中运行。通常,finally代码用于使用.dispose()清除非托管代码的本地声明。

回答

最终尝试捕获是非常重要的构造。我们可以确定,即使抛出异常,也会执行finally块中的代码。处理外部资源以释放它们非常重要。垃圾回收不会帮我们做到这一点。最后,我们不应该具有return语句或者引发异常。可以这样做,但这是一种不好的做法,并且可能导致不可预测的结果。

如果我们尝试以下示例:

try {
  return 0;
} finally {
  return 2;
}

结果将是2 :)

与其他语言的比较:从最后返回

回答

最终,代码块使我们作为开发人员可以自己整理一下,而不管try {}代码块中的代码前面的动作是否遇到错误,并且有其他人指出,这主要是在释放资源的过程中/套接字/结果集,将连接返回到池等。

@mats是非常正确的,总有可能发生"硬"故障,最后,程序块不应该包含关键任务代码,而这些代码必须始终在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();
}

因此,我们可以捕获许多类型的异常,对它们进行不同的处理(第一种允许执行try {}以外的任何事物,第二种有效地返回),但始终要整洁地清除。

回答

有以下几点使finally块有用:

  • 如果从try或者catch块返回,则在将控制权交还给调用函数之前,finally块仍将执行
  • 如果catch块中发生异常,或者try块中发生未捕获的异常类型,则finally块中的代码仍将执行。

这些使块最终成为关闭文件句柄或者套接字的绝佳选择。

回答

@iAn和@mats:

通常,我不会"拆卸"最终{}中在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();  
}

回答

在Java中,无论我们使用的是"返回",只是运行try块还是捕获了异常,我们都可以将它用于任何要执行的操作。

例如,关闭数据库会话或者JMS连接,或者取消分配某些OS资源。

我猜它在.NET中类似吗?