java:无法重新抛出exception:未处理的exception类型exception

我想捕获exception,记录它,设置一个标志,并重新抛出相同的exception

我有这个代码:

public Boolean doJobWithResult() { boolean result = true; final Feed feed = Feed.findById(feedId); try { feed.fetchContents(); } catch (Exception ex) { result = false; Logger.info("fetching feed(%d) failed", feedId); throw ex; } return result; } 

但eclipse在throw ex中抱怨,告诉“未处理的exception类型exception”,并建议我在它周围添加一个try-catch块。

实际上,我希望调用此方法的进程能够处理exception,而不是自己处理它……如果一切正常,我只想返回true,如果有exception则记录它

另一方面,我可以将exception包装在另一个exception中,但我不能抛出相同的exception。

任何想法?

我认为这里有各种各样的事情要提到:

  1. 你想要doJobWithResult()在成功时返回true,在失败时返回false,或者在成功时返回任何内容并在失败时抛出exception。 两者同时是不可能的。 在第一种情况下,捕获exception,记录它并返回false,在第二种情况下,更改签名以返回void并抛出exception并在调用者中处理它。
  2. 这是一个不要捕获exception,记录并重新抛出它。 为什么? 因为您的方法的潜在调用者不知道您已经记录它,并且也记录它。 抛出exception(在这种情况下调用者必须处理它)或捕获它并处理它(记录它)。
  3. 注意抛出Exception并不会给你的方法的调用者任何关于你的方法可能出错的线索,最好抛出更多特定的exception,或者在用户定义的exception中包装exception并重新抛出它。
  4. 此外,如果抛出Exception ,调用者可能会想要捕获Exception而不会注意到它也会捕获每个RuntimeException(因为它派生自Exception ),这可能不是所希望的行为。

你的doJobWithResult方法需要声明它可以抛出exception:

 public Boolean doJobWithResult() { 

 public Boolean doJobWithResult() throws Exception { 

如果向方法签名添加throws Exception ,则可以抛出相同的exception。 否则,您可以抛出RuntimeException 。

 public Boolean doJobWithResult() { boolean result = true; final Feed feed = Feed.findById(feedId); try { feed.fetchContents(); } catch (Exception ex) { result = false; Logger.info("fetching feed(%d) failed", feedId); throw new RuntimeException(ex); } return result; } 

在这种情况下,你不需要指出public Boolean doJobWithResult()抛出一些东西,但确保你以后正确处理它(捕获或期望你的线程停止……它是一个RuntimeException毕竟)。

如果doJobWithResult不必处理exception,则删除catch块并在方法签名中添加“throws Exception”。 exception日志记录可以在必须在相应的try / catch块中处理Exception的类/方法中完成。

由于检查了Exception ,因此捕获Exception的另一种方法是将方法声明为抛出它:

 public Boolean doJobWithResult() throws Exception { // ... } 

没有必要在catch块中将结果设置为false,因为不会返回该值(因为我们抛出exception)。

您的方法还应该声明它抛出exception,因此客户端将被强制处理它。

还要考虑使用更具体的exception,在这种特殊情况下会抛出exception。

添加throws Exception方法的throws Exception 。 你也不需要添加result = false; 在你的catch块中。

我认为如果无法恢复feed.fetchContents()方法的任何失败,那么处理此exception的方式非常合适。 (想法最好停止而不是继续)除此之外,我建议你使用更具体的exception层次结构。

我从有效的java书中得到的另一件事是,如果你编写这样的方法,你必须用@throw(在注释中)记录原因。

您可以抛出未经检查的exception

  Logger.info("fetching feed(%d) failed", feedId); throw new RuntimeException(ex);