使用throw有什么用?并在捕获?

时间:2012-01-07 00:55:23

标签: exception

根据我的理解throw会导致异常。 看起来它可用于测试您的catch例外。

  • 它有什么好处/用途?你为什么要故意造成例外?
  • 为什么在throw中使用catch?似乎它只是为了引起异常而捕获异常。

    try
    {
        //blah
    }
    catch
    {
        throw; 
    }
    

8 个答案:

答案 0 :(得分:3)

throw; 重新抛出当前异常。它用于何时捕获异常并对自己进行处理,但仍然希望异常或多或少地传播,就像从未捕获过一样。

区别(用C语言表示throw;的语言)就是当你重新抛出异常时,原始堆栈跟踪基本保持不变。 (它包括重新抛出异常的行,而不是相应try块中发生异常的行,但是保留整个堆栈跟踪。)如果你说throw the_exception_you_caught;,它通常会被处理掉好像你从那里抛出了一个全新的例外 - 现有的堆栈跟踪被删除,一个新的堆栈跟踪从那一点开始。

答案 1 :(得分:1)

例外是错误处理的机制。例如,您可以抛出异常以指示Web服务调用已超时,或者提供给方法的错误输入。我们的想法是调用代码知道如何处理这些异常并优雅地处理它们 - 可能在输入错误的情况下(通过提示用户)或通过第二次尝试标注来修复错误。

catch块是您处理错误的地方,在某些情况下,您可能希望在运行的方法中进行一些本地清理,但是您仍然需要向调用方法报告错误,所以你再次抛出异常(或抛出一个不同的,可能更通用的或特定的异常),然后在你的调用代码中处理它。

答案 2 :(得分:1)

描述

例如,您可以执行此操作,记录某些内容并将异常提交给调用方法/程序集。

您可以处理异常并向调用方发出异常信号,而不是返回指示方法是否成功的boolean

这对于单元测试等非常有用。

示例

try
{
    //blah
}
catch
{
    // log exception to textfile of database
    throw; 
}

答案 3 :(得分:1)

这是.Net代码中的常见模式。当调用者想要记录,包装或响应异常然后将其传递回调用者时使用它。例如

try { 
  SomeFunction(); 
} catch { 
  CloseMyResource();
  throw;
}

throw vs throw exceptionVariable的优势在于throw保留了原始堆栈跟踪。捕获异常的下一个人会看到原始堆栈跟踪。这主要是为了跟踪深度调用堆栈中的错误。

答案 4 :(得分:1)

如果你想在这里进行一些日志记录或者一些清理,你会重新抛出相同的异常,但是仍然希望调用堆栈中的调用函数必须处理相同的异常。

更典型的用途是:

try {
    // ...
} catch (EmailException ex) {
    SMS.AlertError("Email is not working", ex);
    throw;
}

如果您throw ex,您将从例外中删除诸如调用堆栈之类的信息。

上面的一些函数:

try {
    // ...
} catch (Exception ex) {
    WorkFlowProblems.Add(new OrderNotSentException("Email did not work", ex));
    View.ShowError("Could not send order!");
}

在这里你创建一个新的异常并将它的“内部异常”设置为原始原因。对于多部分系统来说,这是一个很好的方法,可以获得关于出错和在什么级别上的正确信息。

答案 5 :(得分:1)

我认为将一个throw视为对代码中的异常而不是原因的明智反应可能会更好。语义我知道,但它有帮助。

您在catch中添加了一个不同的异常来添加信息。您将可能是通用操作系统异常转换为对您的应用程序有意义的异常。例如可能会捕获内存不足异常,并将内存不足的新异常作为内部异常抛出,例如“在计算宇宙生命和一切生命的答案时出错”。更有用的是只有内存不足的例外。

你可以单独使用'throw'作为重新抛出。捕获允许您在重新抛出之前执行某些操作。如果我们正在谈论C#,请查看'finally'。

如果发生了非常糟糕的事情,那就不应该发生,那么你可以通过抛出异常来中止并通知调用者。这意味着您不需要让每个方法都返回结果代码,并且每个调用者都需要测试错误/成功代码。它也很好地抽象了谁处理这种“例外”,或者即使你把它留给操作系统。

快速回答......它使您的代码更简单,并让您更好地控制中止和处理异常。将其视为消息传递/中止系统。

答案 6 :(得分:0)

这样做可以保留堆栈跟踪。在您的示例中,它没有用,但是,您可以捕获异常,记录它然后重新抛出,以便异常起泡以由更高的代码处理。

答案 7 :(得分:0)

抛出异常(在我看来)最有用的地方是当你想要创建一个新对象的实例时,实例需要在创建时失败,在这种情况下可以使实例成为保持为null(因为构造函数不会“返回”任何东西......例如......

Foo foo = new Foo(); //

//在这一行foo可能是也可能不是你想要的东西,这取决于创建Foo的任何条件。

所以,Foo会抛出一个例外,你可以这样做:

Foo foo = null;
try{
  foo = new Foo();
}catch(FooException fe){
  //here you can find out if Foo didn't get instantiated as you wanted it to
}

//and here you can test if foo is still null.