Java中重新抛出异常

4
在Java中,有可能重新抛出异常,但这样做有什么好处吗?
7个回答

6

当您不知道如何处理异常,但希望记录异常被抛出时,需要重新抛出异常。重新抛出异常允许您捕获需要记录的堆栈信息,并将异常传递到调用者处理。


5

当您需要对异常进行特殊处理(例如日志记录、清理等)但不能完全“处理”它时,通常会先进行处理然后再重新抛出异常。请注意,在许多情况下(尤其是清理资源时),您可能需要使用finally子句而不是catch/rethrow。


4
有时候,你希望一个方法抛出特定类型的异常,但是在方法内部可能会发生其他异常,这种情况很少见。我经常使用我的期望异常来包装引起异常的原因,并重新抛出期望的异常。
当你无法确定异常是否导致操作失败直到控制流传递到调用方法(或其祖先方法)时,这个技巧非常有用。如果最终进程失败了,我可以追溯到堆栈跟踪以查看原因。

1

真实案例

以下是我在实际工作中需要重新抛出Java异常的一些情况:

  • 在进行JDBC调用时,我会捕获SQLException。然而,Postgres会抛出带有附加数据和状态的PSQLException。在测试边缘情况时,我们能够破坏数据库,并且我们希望记录器具有关于异常和状态的非常特定的数据。我们将原始异常包装在一个新的异常中,其中包含更多关于服务器状态的数据,并重新抛出。
  • 在实现文本解析器时,我想捕获许多运行时解析异常,例如NumberFormatException,并将它们传递到堆栈上,同时提供有关导致解析异常的文本及其来源的附加数据。
  • 我的同事告诉我他曾经参与的一个项目,其中每个异常都被包装在另一个异常中,这两种类型分别是RetryableException和FatalException。在Retryable异常的情况下,应用程序会等待并在固定时间后重试操作。我对这种设计感觉不确定,但我可以看到它作为处理某些事务问题的临时措施。
  • 在某些情况下,我将使用已定义高级别异常的现有API,并且我将执行会引发不相关异常(我认为真正属于RuntimeException)的操作 - 然后将异常重新抛出作为更一般异常的原因。
  • 我能想到的最纯粹的情况是,当您想要添加附加数据时,您可能需要重新抛出异常。例如:
    public bizMethod() throws CoolBizLogicException {
        int policyId = getPolicyId("bar");
        try {
          coolBizLogic(foobar); // this throws an exception
        }
        catch (CoolBizLogicException cble) {
          cble.setPolicyId(policyId);
          throw cble;
        }
    }

1

我已经好几年没写Java了,但是从我记得的来看,它就像其他语言一样有异常和面向对象编程。异常可以被子类化,通常情况下,你会想要捕获许多异常的基类,但可能无法处理所有异常。所以说,假设你正在处理远程文件传输,并且想要捕获所有的IOErrors,因为你可以处理其中大部分,但不能处理DiskFull。你可以重新抛出该异常,让上层代码处理,但需要重新执行传输来处理其他问题,例如TransmissionFailed。


1

如果你能以某种方式证明需要重新抛出捕获到的同一异常,我会认为你的设计存在问题。

捕获一个异常并重新抛出另一个异常是很有道理的。例如,您可能希望添加原始异常中没有的详细信息。


0

我不这么认为。如果你处理不了,就别去捕捉它。


除非您总是知道异常的原因,否则在进一步调查之前,您不确定是否可以处理它。 - Rik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接