无法访问的代码 - 尝试捕获 - 最终
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
块也可能无法成功返回。
鉴于这种假设,有一些逻辑路径可以达到catch
和finally
。并且由于这些都没有返回,所以相同的逻辑路径将完全结束整个try/catch/finally
并导致在它之后到达代码。
基本上,编译器(以及它的设计者)更喜欢简单的规则而不是复杂的规则。简单的规则更易于测试和支持,并且可以向后兼容未来的版本。因此,对于正在更彻底地分析逻辑的人来说,无法达到该代码,对编译器而言,这是完全可能的。
编译器看到你有一个用于catch
的Exception
块并假设它可能发生(因为你告诉它可以)。由于finally
可以在catch
之后到达,因此跟随它的代码也是如此(因为catch
块无法终止函数,finally
也没有)。第二个你注释掉catch
,编译器知道它永远不会在任何条件下达到最终,因此错误。
您不需要考虑try块中的return语句,而是考虑try块本身。它看到try块并且需要catch在那里(可选地它可以有一个finally块)。如果删除catch语句,try块不知道如果发生错误该怎么办,所以不会到达它下面的任何东西(因此无法访问代码错误)
编译器认为“好吧,如果try块确实输出错误,这段代码会发生什么 - 下面的代码将无法执行,因为我没有被告知如何从该错误中恢复”
当你有一个catch语句时,编译有点想 - 我将尝试“CODE HERE”,如果出错,我将捕获错误并执行“CODE HERE”,并且我可以选择执行“CODE HERE”。然后我会像正常一样在块下面执行。
以上是关于无法访问的代码 - 尝试捕获 - 最终的主要内容,如果未能解决你的问题,请参考以下文章