try {} finally {}使用返回值构造

Yur*_*uri 26 java

我想知道为什么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";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以也不应该奏效.java规范声明finally始终执行块,但同时已指定返回值.所以要么你不能执行该return "b"语句,因为你已经退出return "a",这是不正确的.

但是,另一个选择是执行该return "b"语句,从而完全忽略该return "a"语句......

我会说两者都是错的,我希望这不会编译.然而,它编译并运行良好.我将把答案作为一个很好的练习留给读者;).

基本上我的问题是:除了不好的做法,这会被认为是一个Java错误,还是除了混淆之外还有其他奇妙的用途?

编辑:

问题不是如果它是一个bug,已经得到了回答,但它有不错的用例吗?

Mar*_*oun 19

一切都按预期完成,没有错误.当你有疑虑时,JLS就是你的救星:

JLS - 14.20.2.执行try-finally和try-catch-finally:

如果try由于任何其他原因导致finally块的执行突然完成,则执行该块,然后有一个选择:

  • 如果finally块正常完成,则try语句
    突然完成,原因是R.

  • 如果finally块由于原因S而突然完成,则try语句突然完成,原因S(并且原因R被
    丢弃).

会覆盖try块中的值.

returninside finally丢弃可以在try子句中抛出的所有异常.