无法无误地编译无法访问的代码 - 如何?

根据我的理解,以下代码不应编译,因为“我无法访问”语句在return.


但是,当我运行这段代码时,它编译得非常好。


同样来自 JLS: Unreachable Statements它不应该编译。


来自规范,在 14.21 Unreachable Statements:


如果以下两项都为真,try 语句可以正常完成:


try 块可以正常完成,或者任何 catch 块都可以正常完成。


如果 try 语句有一个 finally 块,那么 finally 块可以正常完成。


这里的try块不能正常完成,但是catch块和finally块一样可以,所以我在这里很困惑


    public class Test1 {

     public static void main(String[] args) {

        try {

            return;


        } catch (Exception e) {

            System.out.println("catch");


        } finally {

            System.out.println("finally");

        }

        System.out.println("I am unreachable??!!!");

    }

}

有人可以帮助我理解这种行为吗?


叮当猫咪
浏览 165回答 3
3回答

万千封印

我相信这些是JLS 14.21的相关引用:一个不是 switch 块的空块可以正常完成,如果它是可到达的。不是 switch 块的非空块可以正常完成,如果其中的最后一条语句可以正常完成。不是 switch 块的非空块中的第一个语句是可到达的,如果该块是可到达的。非空块(不是 switch 块)中的每个其他语句 S 都是可达的,如果 S 之前的语句可以正常完成。所以你的System.out.println("I am unreachable??!!!");语句是可达 iff(即“当且仅当”)try 语句可以正常完成,这导致下一个引用:如果以下两项都为真, try 语句可以正常完成:try 块可以正常完成,或者任何 catch 块都可以正常完成。如果 try 语句有一个 finally 块,那么 finally 块可以正常完成。由于您的catch块可以正常完成,并且您有一个finally可以正常完成的块,因此该try语句可以正常完成。因此System.out.println("I am unreachable??!!!");,无论块return;内的语句如何,它后面的语句都被认为是可达的try。注意or在try 块可以正常完成,或者任何 catch 块都可以正常完成。这需要try块或至少其中一个catch块才能正常完成。它不需要try块和catch块都正常完成。最后,这种行为背后的逻辑:编译器不应该分析 try 块是否可以抛出Exception. 原因是Exception类层次结构包括受检异常和非受检异常,并且未受检异常没有在throws子句中声明(如果您替换Exception为某些受检异常,例如IOException,编译器会抱怨您的 try 块永远不会抛出该异常,这将使该catch块不可达)。因此,由于您有一个catch (Exception e)可以正常完成的块,编译器假定该 catch 块是可达的,因此整个 try 语句可以正常完成,即使该try块无法正常完成。finally块,如果存在,也必须能够正常完成,因为该finally块也被执行了,所以如果不能正常完成,整个try语句也不能正常完成。

守着一只汪

你有回报。如果有异常直接去捕获怎么办。因此,它在编译器方面并非不可访问,并且正在成功编译。如果您也将在 catch 中返回,则编译将失败此外,根据JLS 14.21:如果在 break 目标中没有 try 语句的 try 块包含 break 语句,或者有 try 语句的 try 块包含 break 语句并且这些 try 语句的所有 finally 子句可以完成,则可达 break 语句将退出语句一般。当您在 try 和 catch 中都返回时,请参阅下面的输出:jshell>  public class Test1 {   ...>     public static void main(String[] args) {   ...>         try {   ...>             return;   ...>   ...>         } catch (Exception e) {   ...>             return;   ...>   ...>         }   ...>   ...>         System.out.println("I am unreachable??!!!");   ...>     }   ...> }|  Error:|  unreachable statement|          System.out.println("I am unreachable??!!!");|          ^------------------------------------------^当您在 finally 语句中返回并且编译将失败时,情况也会类似。在以下情况下,语句 post try 将被视为可达:1) Try has a return statement with catch and finally not having return statement2) Try does not have a return statement with catch having or not having return statement and finally not having return statement3) Try, catch and finally not having return statement

jeck猫

试图给出一个更简单的问题原因,代码是可访问的,以防在 try 块中发生异常。在这种情况下,控制会进一步转到 catch 块,然后是 finally 块。在 finally 块之后,将执行特定的语句。try {            return;                                 //line 1        } catch (Exception e) {            System.out.println("catch");            //line 2        } finally {            System.out.println("finally");          //line 3        }        System.out.println("I am unreachable??!!"); //line 4这意味着,有 2 种情况,因此有 2 个流:第 1 行 -> 第 3 行 -> 返回(如果没有例外)第 1 行(发生异常) -> 第 2 行 -> 第 3 行 -> 第 4 行(以防 try 出现异常)只有当我们不留下任何控制权到达那里的可能性时,这条线才会变得不可到达。有两种方法:从 catch 块返回从 finally 块返回。在这两种情况下,控制权永远不会流向那条线。try {            return;                                 //line 1        } catch (Exception e) {            System.out.println("catch");            //line 2            return;                                 //return control        } finally {            System.out.println("finally");          //line 3            return;                                 //or return from here        }        System.out.println("I am unreachable??!!"); //line 4    我希望现在它可以清楚地说明问题的实际原因。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python