类型擦除会在这里发生吗?

时间:2013-08-01 15:57:38

标签: java exception generics

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

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 个答案:

答案 0 :(得分:3)

我可以提一下,你的代码严重破坏了。 永远不要从finally块中抛出。如果你的try-block抛出了除了你明确捕获的那两个之外的任何其他异常,那么你将冒着掩盖这个异常并抛出 anyException 的风险。这将产生这种隐秘的错误,团队成员可能想要为你计划一次仇杀。

至于您的例外类型,它们都是未经检查的,因此它们不会给您带来方法签名方面的任何麻烦。只是扔掉它们而不宣布。

答案 1 :(得分:1)

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

throw anyException;

会抛出通用Exception,因为anyException的类型只是Exception所以您的方法需要声明throws Exception,这可能过于宽泛。

最简单的解决方案可能是

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

在每个catch块中,或者重写try块的内容,以便可以导致重试的异常类型更少。

除了网络拥塞等短暂问题导致失败以外,您真的想重试吗?

答案 2 :(得分: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'捕获它只意味着您不必为每种可能的类型重复相同的代码。但是如果你想避免在你的方法上“抛出异常” - 那么是的,你需要为每种类型多次捕获/重新抛出。正如有人指出的那样 - 你当前捕获的那些没有被检查,所以你可以高兴地抛出它们,而不必在你的方法签名中声明它。

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

答案 3 :(得分:0)

if (anyException instanceOf RejectedExecutionException) {
  throw (RejectedExecutionException) anyException;
}
else if (anyException instanceof NullPointerException) {
  throw (NullPointerException) anyException;
}