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。
任何想法?
我认为这里有各种各样的事情要提到:
- 你想要
doJobWithResult()
在成功时返回true,在失败时返回false,或者在成功时返回任何内容并在失败时抛出exception。 两者同时是不可能的。 在第一种情况下,捕获exception,记录它并返回false,在第二种情况下,更改签名以返回void
并抛出exception并在调用者中处理它。 - 这是一个不要捕获exception,记录并重新抛出它。 为什么? 因为您的方法的潜在调用者不知道您已经记录它,并且也记录它。 抛出exception(在这种情况下调用者必须处理它)或捕获它并处理它(记录它)。
- 注意抛出
Exception
并不会给你的方法的调用者任何关于你的方法可能出错的线索,最好抛出更多特定的exception,或者在用户定义的exception中包装exception并重新抛出它。 - 此外,如果抛出
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);