3 回答
TA贡献1891条经验 获得超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语句也不能正常完成。
TA贡献1872条经验 获得超3个赞
你有回报。
如果有异常直接去捕获怎么办。因此,它在编译器方面并非不可访问,并且正在成功编译。
如果您也将在 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 statement
2) Try does not have a return statement with catch having or not having return statement and finally not having return statement
3) Try, catch and finally not having return statement
TA贡献1909条经验 获得超7个赞
试图给出一个更简单的问题原因,代码是可访问的,以防在 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
我希望现在它可以清楚地说明问题的实际原因。
添加回答
举报