我想知道为什么Java编译器会接受以下代码:
public class Main {
public static void main(String ... args){
System.out.println("a() = " + a());
}
public static String a (){
try {
return "a";
}catch(Throwable t){
}finally{
return "b";
}
}
}
这可以也不应该奏效。 java规范声明finally
块将始终执行,但同时已指定返回值。所以要么你不能执行return "b"
语句,因为你已经退出return "a"
,这是不正确的。
但是,另一个选择是执行return "b"
语句,从而完全忽略return "a"
语句......
我会说两者都错了,我希望这不会编译。然而,它编译并运行良好。我将把答案作为一个很好的练习留给读者;)。
基本上我的问题是:除了不好的做法外,这会被认为是一个Java错误,还是除了混淆之外还有其他很多用途?
问题不在于如果它是一个bug,已经得到了解答,但它有不错的用例吗?
答案 0 :(得分:19)
一切都按预期完成,没有错误。当你有疑虑时,JLS就是你的救星:
JLS - 14.20.2. Execution of try-finally and try-catch-finally:
如果
try
块的执行突然完成任何其他块 原因R,然后执行finally
块,然后有一个 选择:
如果finally块正常完成,那么try语句
由于原因而突然完成。如果finally块因为S而突然完成,则尝试 声明突然完成原因S(原因R为
丢弃)。
覆盖 try
块中的值。
return
内的 finally
会丢弃try
子句中可以抛出的所有异常。