无法访问的代码 - 尝试捕获 - 最终

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法访问的代码 - 尝试捕获 - 最终相关的知识,希望对你有一定的参考价值。

我知道如果java找到一行代码,保证控件永远不会到达,那么编译器会报告无法访问的代码错误。 考虑以下代码。

    static int method1() {

        try{ return 1; }
        catch(Exception e){ }  // LINE-1
        finally{ }
        System.out.println("abc");  //LINE-2
        return 2;
    }
}

在上面的代码中 保证1个try块通过返回1退出,但是在finally块(LINE-2以后)之后仍然可以访问。 2.如果我评论catch块(LINE-1),则LINE-2变得无法访问。 为什么会如此。编译器是否能够在case-1的try块中看到无条件返回。

答案

这是JLS 14.21的相关部分:

如果满足以下两个条件,则try语句可以正常完成:

  • try块可以正常完成或任何catch块可以正常完成。
  • 如果try语句有finally块,那么finally块可以正常完成。

在这种情况下,尽管您的try块无法正常完成,但它有一个可以正常完成的catch块。 finally块也可以正常完成。

try语句是可以访问的并且可以正常完成,因此可以访问它之后的语句。

如果删除catch块,则上面引用部分中的第一个项目符号不再为真 - 这意味着try语句无法正常完成,并且后面的语句无法访问。

另一答案

一个try块(好的,带有catch)告诉编译器“这里的内容可能会导致异常”。所以编译器假设,即使其中有return语句,try块也可能无法成功返回。

鉴于这种假设,有一些逻辑路径可以达到catchfinally。并且由于这些都没有返回,所以相同的逻辑路径将完全结束整个try/catch/finally并导致在它之后到达代码。

基本上,编译器(以及它的设计者)更喜欢简单的规则而不是复杂的规则。简单的规则更易于测试和支持,并且可以向后兼容未来的版本。因此,对于正在更彻底地分析逻辑的人来说,无法达到该代码,对编译器而言,这是完全可能的。

另一答案

编译器看到你有一个用于catchException块并假设它可能发生(因为你告诉它可以)。由于finally可以在catch之后到达,因此跟随它的代码也是如此(因为catch块无法终止函数,finally也没有)。第二个你注释掉catch,编译器知道它永远不会在任何条件下达到最终,因此错误。

另一答案

您不需要考虑try块中的return语句,而是考虑try块本身。它看到try块并且需要catch在那里(可选地它可以有一个finally块)。如果删除catch语句,try块不知道如果发生错误该怎么办,所以不会到达它下面的任何东西(因此无法访问代码错误)

编译器认为“好吧,如果try块确实输出错误,这段代码会发生什么 - 下面的代码将无法执行,因为我没有被告知如何从该错误中恢复”

当你有一个catch语句时,编译有点想 - 我将尝试“CODE HERE”,如果出错,我将捕获错误并执行“CODE HERE”,并且我可以选择执行“CODE HERE”。然后我会像正常一样在块下面执行。

以上是关于无法访问的代码 - 尝试捕获 - 最终的主要内容,如果未能解决你的问题,请参考以下文章

位置访问时无法捕获的异常

YouTube API v3 over HTTP POST:上传视频时无法设置片段(标题最终为“未知”)

从片段中捕获图像

捕获使剩余模式无法访问

无法在片段内创建对话框

“未捕获的类型错误:无法在 Websocket Angular JS 上读取未定义的属性‘延迟’”