考虑以下代码:
@Test
public void testDeadCode() {
letsThrow();
System.out.println("will never be reached");
}
private final void letsThrow() {
throw new RuntimeException("guess you didnt see this one coming");
}
对我来说, println() 似乎绝对不可能被执行 - 因为调用 letThrow() 会always抛出异常。
因此我是
a) 惊讶于编译器无法告诉我“这是死代码”
b) 想知道是否有一些编译器标志(或 Eclipse 设置)会导致告诉我:你那里有死代码。
死代码编译时错误是由编译器而不是 IDE 定义的。虽然代码确实永远不会被执行,但它并不违反 Oracle 文档中有关无法访问语句的任何规则。
From 无法访问的语句 http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21
本节专门对“可达”一词进行精确解释。这个想法是,从包含语句的构造函数、方法、实例初始值设定项或静态初始值设定项的开头到语句本身,必须存在一些可能的执行路径。分析考虑了陈述的结构。除了对条件表达式为常量true的while、do、for语句进行特殊处理外,在流分析中不考虑表达式的值。
专门针对这种情况的规则与您创建的块是否可达有关。 (当且仅当=当且仅当)
不是 switch 块的空块可以正常完成,前提是它是可访问的。
不是 switch 块的非空块可以正常完成,前提是其中的最后一条语句可以正常完成。
不是 switch 块的非空块中的第一个语句是可达的,当且仅当该块可达。
不是 switch 块的非空块中的所有其他语句 S 都是可达的,前提是 S 之前的语句可以正常完成。
The letsThrow
方法满足代码工作块的标准,并且在技术上正常完成。它抛出异常,但它完成了。在确定该代码块是否在实际使用中时,不考虑它是否抛出有保证的异常,只是能否达到。在大多数情况下,只有当涉及 try/catch/returns(这些是规则的大部分)时,才会发现死代码。
考虑以下更简洁的版本:
@Test
public void testDeadCode() {
System.exit(0);
System.out.println("will never be reached");
}
除了勤奋使用覆盖率工具之外,没有真正的对策,但示例中好的一面是每次运行代码时都会看到有保证的异常。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)