调用堆栈:catch vs. throws

时间:2013-05-03 18:27:41

标签: java exception

何时使用“catch”以及何时使用“throws”?

try {
    //stuff
} 
catch (MyException me) {
    //stuff
}

public void doSomething() throws MyException {
    //stuff
}

在“throws”的情况下,在catch栈中放置我的catch?

Main
    ----- Function 1
        ----- Function 2
            ----- Function 3 (generate exception)

如果我将异常从函数3传播到函数2,为什么函数2不应该这样做呢?所以最后我最终会管理“main”中的所有异常,我认为将所有代码放在try块中并不是一个go0d实践,不是吗?

那么选择“捕获”和“抛出”之间的逻辑方式是什么?在第二种情况下,我应该将我的捕获放在调用堆栈中?

3 个答案:

答案 0 :(得分:2)

它们基本上是相反的。 throws表示允许函数抛出异常; catch表示块(try)块期望可能抛出异常,并准备处理它。

采取球比喻,投手throws是捕手所期望的例外。接球手catches球并以某种方式处理它。 (好吧,也许这个比喻有点偏,因为捕手通常把它扔回投手处理球。:))在这里,投手是一种方法,捕手是try-catch-[finally]块。 / p>

答案 1 :(得分:0)

当方法的调用者需要捕获它或传递它时,你应该声明一个方法抛出一个已检查的异常。只要你准备好处理那个异常就应该捕获异常。

例如,如果您正在编写一个具有图形界面的程序,该图形界面也具有从文件读取的核心,则核心类没有装备以告知用户存在错误,这是图形界面的工作。因此,核心程序中的getSomethingFromFile()等方法可能会抛出IOException。如果图形界面调用getSomethingFromFile()并确定存在读取错误,则图形界面可以向用户显示对话框,因此它已准备好然后捕获异常。在这种情况下,getSomethingFromFile()调用应该包含在try / catch中。

答案 2 :(得分:0)

如果您要采用throw - catch方法来处理错误,那么实际的错误处理必须由具有责任的组件完成,特别是因为这允许你可以将逻辑封装在它所属的位置。

这个例外是由某个知道如何处理它的人以及必须采取的行动所引起的。在某些特定情况下,您可以通过将异常包装在另一个异常(将异常设置为其原因)来重新抛出异常。以任何ORM为例,任何低级异常都包含在例如PersistenceException中,其中可能有SQLSyntaxException作为其原因。

如果您没有适当的工具来管理特定上下文中的异常,并且您希望将其传播到可以正确管理的更高层/层,那么

throws就会发挥作用。

让我举一个“大图片示例”:

  1. 实体保存到数据库
  2. 通讯错误
  3. 异常抛出,因此您的持久性对象必须处理
  4. 抓住它,将其包装并重新抛出它作为您自己的异常之一(我反对让持久性异常传播到更高层...但这只是我)。
  5. 持久性抛出模型的捕获异常。
  6. 模型重试操作。
  7. 另一次失败(同样 wrap + throw )。
  8. 模型通知失败,提升报告到视图。这就是我所说的被“知道”该做什么的人抓住
  9. 视图显示“今天不保存,对不起”给用户。
  10. 该示例包含throwcatch个案例,我希望有助于澄清。