在 java 的 finally 子句中使用 return 语句是危险的



看看下面的代码。尽管 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");这是潜在的危险。

相关内容

最新更新