在总是抛出方法之后如何检测死代码?

2024-06-11

考虑以下代码:

@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(使用前将#替换为@)

在总是抛出方法之后如何检测死代码? 的相关文章

随机推荐