最近我很惊讶地发现,在Java中可以在finally块中使用return语句。
似乎很多人认为像“Don't return in a finally clause”中描述的那样做是一件坏事。再深入一点,我还发现了'Java's return doesn't always‘,它在finally块中显示了一些非常可怕的其他类型的流控制示例。
所以,我的问题是,谁能给我一个例子,在finally块中的return语句(或其他流控制)可以产生更好的/更好的可读性的代码?
发布于 2008-09-07 20:17:35
几年前,我真的很难追查到一个由它引起的bug。代码类似于:
Object problemMethod() {
Object rtn = null;
try {
rtn = somethingThatThrewAnException();
}
finally {
doSomeCleanup();
return rtn;
}
}发生的情况是,在其他代码中抛出了异常。它被捕获、记录并在somethingThatThrewAnException()方法中重新抛出。但是异常并没有通过problemMethod()向上传播。经过很长一段时间的研究,我们终于找到了返回方法。finally块中的返回方法基本上阻止了try块中发生的异常向上传播,即使它没有被捕获。
正如其他人所说,虽然根据Java规范,从finally块返回是合法的,但这是一件坏事,不应该这样做。
发布于 2008-09-07 13:50:01
如果你使用-Xlint:finally,javac最终会警告你返回。最初javac不会发出警告--如果代码出了问题,它应该无法编译。不幸的是,向后兼容意味着无法禁止意料之外的巧妙愚蠢。
可以从finally块抛出异常,但在这种情况下,所展示的行为几乎肯定是您想要的。
发布于 2008-09-07 03:31:57
将控制结构和返回添加到finally{}块只是“因为你可以”滥用的另一个例子,这种滥用实际上分散在所有开发语言中。Jason的建议是正确的,它很容易成为维护的噩梦-反对函数提前返回的论点更适用于这种“延迟返回”的情况。
Finally块的存在只有一个目的,那就是允许您完全清理自己,而不管前面的代码中发生了什么。这主要是关闭/释放文件指针、数据库连接等,尽管我可以看到它被延伸到添加定制审计。
任何影响函数返回的东西都应该在try{}块中。即使你有一个方法,你检查了一个外部状态,做了一个耗时的操作,然后再次检查该状态,以防它变得无效,你仍然希望在try{}中进行第二次检查-如果它位于finally{}中,并且long操作失败,那么你将不必要地第二次检查该状态。
https://stackoverflow.com/questions/48088
复制相似问题