这是一个关于 finally 块中返回的有趣比较,其中 - Java/C#/Python/JavaScript:(存档链接)
从最后归来
就在今天,我正在帮助解决 Java 中的一些错误并遇到了一个有趣的问题——如果在 try/catch 语句中使用 return 会发生什么?finally 部分是否应该启动?我将问题简化为以下代码片段:
下面的代码打印出什么?
class ReturnFromFinally {
public static int a() {
try {
return 1;
}
catch (Exception e) {}
finally{
return 2;
}
}
public static void main(String[] args) {
System.out.println(a());
}
}
我最初的猜测是,它应该打印出来1
,我正在打电话
return
,所以我假设会返回一个。但是,事实并非如此:

我理解逻辑,最后必须执行部分,但不知何故我对此感到不安。让我们看看 C# 在这种情况下做了什么:
class ReturnFromFinally
{
public static int a()
{
try {
return 1;
}
catch (System.Exception e) {}
finally
{
return 2;
}
}
public static void Main(string[] args)
{
System.Console.WriteLine(a());
}
}

我更喜欢这种行为,控制流不能在 finally 子句中被弄乱,所以它可以防止我们在脚下开枪。为了完整起见,让我们检查一下其他语言的功能。
Python:
def a():
try:
return 1
finally:
return 2
print a()

JavaScript:
<script>
function ReturnFromFinally()
{
try
{
return 1;
}
catch (e)
{
}
finally
{
return 2;
}
}
</script>
<a onclick="alert(ReturnFromFinally());">Click here</a>

C++ 和 PHP 中没有 finally 子句,所以我不能尝试我有编译器/解释器的最后两种语言。
我们的小实验很好地表明,C# 对这个问题有最好的方法,但我很惊讶地发现,所有其他语言都以同样的方式处理这个问题。