带返回值的 try finally 构造 [重复]

Posted

技术标签:

【中文标题】带返回值的 try finally 构造 [重复]【英文标题】:try finally construct with return values [duplicate]带返回值的 try finally 构造 [重复] 【发布时间】:2015-02-16 02:24:19 【问题描述】:

我想知道为什么 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 错误,或者除了混淆之外还有其他美妙的用途吗?

编辑:

问题不在于它是否是一个已得到解答的错误,而是它有很好的用例吗?

【问题讨论】:

这个问题是我本周读到的最有趣的问题之一。但是,据我了解,try 块永远不会引发异常。 非常意外的输出!! 问题有很多重复。 ***.com/questions/65035/…***.com/questions/4185340/…***.com/questions/19899155/… ... finally 块有权覆盖任何返回值。所以你的代码应该返回“b”。 @Hichamov 此输出中有什么意外? 【参考方案1】:

一切都按预期工作,这里没有错误。当您有疑问时,JLS 是您的救星:

JLS - 14.20.2. Execution of try-finally and try-catch-finally:

如果 try 块的执行突然完成对于任何其他 原因R,那么finally块被执行,然后有一个 选择:

如果 finally 块正常完成,则 try 语句 出于 R 的原因突然完成。

如果 finally 块由于原因 S 突然完成,则 try 语句由于原因 S 突然完成(原因 R 是 丢弃)。

覆盖 try 块中的值。

return inside finally 丢弃所有可以在try 子句中抛出的异常。

【讨论】:

好的,所以没有错误。谢谢,但是用例@Yuri 我真的想不出有什么用处。 @Yuri 为什么会有用? @Yuri 那有什么了不起的? @Tom 你不太擅长代码混淆,是吗? ;-)。开个玩笑,我对这种结构的完全无用有点讽刺:-)。

以上是关于带返回值的 try finally 构造 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

关于finally对返回值的影响

C# - Try-Catch-Finally 返回 [重复]

try-finally的时候try里面带return

try{ } catch{ } finally{ }

try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,什么时候被执行,在return前还是后?

Java面试题|return与finally的执行顺序对返回值的影响