看看下面的代码。尽管 catch 子句本身会引发异常,但 finally 块的 return 语句会导致该异常被吞噬。即使 catch 块中出现问题,此方法也会返回 420。
private static int foo() throws Exception
{
try {
throw new Exception("try");
} catch (Exception ex) {
throw new Exception("catch");
} finally {
String s = "";
return 420;
}
}
如果遇到异常,则应返回其他内容。仅当引发该异常的变量在最终返回语句中使用时,异常才危险。考虑一下:
int a;
try{
//...
}catch(Exception e){
//a throws an exception somehow
}finally{
returns a;
}
当你像这样在另一边使用a
时:
a += 1;
你会得到一个危险的例外。
我的建议是这样做:
try{
//...
}catch(Exception e){
//a throws an exception somehow
returns -1;
}finally{
returns a;
}
而在另一边:
if(return_value == -1) // skip or do something else;
这样,您就不会在另一边收到不可预测的异常。
最后返回是一个非常糟糕的主意。它不仅会隐藏您自己引发的异常,还会隐藏虚拟机错误,例如堆栈溢出或内存不足错误。这些错误可以在任何时候抛出,包括当数据结构的关键不变量不成立时,并且无法预测程序将做什么。
在您的情况下,这是安全的,但是如果我们稍微改变您的场景
private static FileReader foo() throws Exception{
try {
throw new Exception("try");
} catch (Exception ex) {
throw new Exception("catch");
} finally {
return new FileReader("");//this may also throw something
}
}
现在,因为我们没有在您的文件系统中指定正确的路径,return new FileReader("");
会抛出FileNotFoundException
,我们将丢失 catch 部分中抛出的异常,new Exception("catch");
这是潜在的危险。