0

我想我会在这段代码中丢失有关特定异常类型的信息。如何保留 Exception 的类型,以便不必将通用 Exception throws 子句添加到包含以下代码的方法中?我认为这与正确使用泛型有关。指导将不胜感激。

for( int i = 0; i < retries; i ++ ) {
    Exception anyException = null;
    try {
        Future<Object> returnedObj = threadPool.submit(task);
        toReturn = returnedObj.get(timeout, timeunit);
        break;
    } catch (RejectedExecutionException ex) {
        anyException = ex;
    } catch (NullPointerException ex ) {
        anyException = ex;
    }
    ...
    finally {
       ...
       if(i == retries -1 && anyException != null) {
           throw anyException;
       }
    }
}
4

4 回答 4

3

我可以提一下您的代码已严重损坏。永远不要从 finally 块中抛出。如果您的 try-block 抛出除了您明确捕获的两个异常之外的任何其他异常,您将面临此异常将被屏蔽并抛出anyException的风险。这将产生如此隐秘的错误,以至于团队成员可能想要计划对你的仇杀。

至于你的异常类型,它们都是未选中的,所以它们不会给你任何关于方法签名的麻烦。不声明就扔掉。

于 2013-08-01T16:22:29.483 回答
1

问题不在于通用代码,而在于过于宽泛的局部变量类型。

throw anyException;

抛出一个泛型Exception,因为类型anyException只是Exception你的方法需要声明throws Exception它可能过于宽泛。

最简单的解决方案可能是把

if(i == retries -1) {
  throw ex;
}

在每个 catch 块中,或重新处理try块的内容,以减少可能导致重试的异常种类。

除了由于网络拥塞等暂时性问题而导致的失败之外,您真的要重试任何事情吗?

于 2013-08-01T16:33:17.740 回答
1

我认为这就是你想要做的:

try {
    Future<Object> returnedObj = threadPool.submit(task);
    toReturn = returnedObj.get(timeout, timeunit);
    break;
} catch (Exception ex) {
   if(i == retries -1) {
       throw ex;
   }

捕获前 N 个异常,并且只重新抛出最后一个异常。像这样捕获和重新抛出它不会丢失任何类型信息。通过基类 'Exception' 捕获它只是意味着您不必为每种可能的类型重复相同的代码。但是,如果您想在您的方法中避免“抛出异常” - 那么是的,您将需要为每种类型多次捕获/重新抛出。正如有人指出的那样 - 您当前捕获的那些没有被检查,因此您可以愉快地抛出它们而无需在您的方法签名中声明它。

我应该说仅仅吞下这样的异常并不是一个好主意。至少在某个地方记录它们......

于 2013-08-01T16:33:58.647 回答
0
if (anyException instanceOf RejectedExecutionException) {
  throw (RejectedExecutionException) anyException;
}
else if (anyException instanceof NullPointerException) {
  throw (NullPointerException) anyException;
}
于 2013-08-01T17:00:49.750 回答