我想我会在这段代码中丢失有关特定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;
}
}
}
答案 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;
}