考虑以下代码:
@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() - 因为对 letsThrow() 的调用将总是 抛出异常。
我就是这样
a) 惊讶于编译器不能告诉我“这是死代码”
b) 想知道是否有一些编译器标志(或 eclipse 设置)会导致告诉我:你那里有死代码。
最佳答案
死代码编译时错误是由编译器而不是 IDE 定义的。虽然代码确实永远不会执行,但它并不违反 Oracle 文档中关于无法访问语句的任何规则。
This section is devoted to a precise explanation of the word "reachable." The idea is that there must be some possible execution path from the beginning of the constructor, method, instance initializer, or static initializer that contains the statement to the statement itself. The analysis takes into account the structure of statements. Except for the special treatment of while, do, and for statements whose condition expression has the constant value true, the values of expressions are not taken into account in the flow analysis.
专门针对这种情况的规则与您创建的 block 是否可达有关。 (iff = 当且仅当)
An empty block that is not a switch block can complete normally iff it is reachable.
A non-empty block that is not a switch block can complete normally iff the last statement in it can complete normally.
The first statement in a non-empty block that is not a switch block is reachable iff the block is reachable.
Every other statement S in a non-empty block that is not a switch block is reachable iff the statement preceding S can complete normally.
letsThrow
方法符合工作代码块的标准,并且在技术上正常完成。它抛出一个异常,但它完成了。在确定该代码块是否在其实际使用中时,不会考虑它是否抛出有保证的异常,只考虑它是否可以到达。在大多数情况下,死代码只有在涉及 try/catch/returns 时才会被发现,这是大部分规则。
考虑以下更简洁的版本:
@Test
public void testDeadCode() {
System.exit(0);
System.out.println("will never be reached");
}
除了勤奋地使用覆盖工具之外,没有真正的应对方法,但您示例中的亮点是每次运行代码时都会看到有保证的异常。
关于java - 在总是抛出方法之后如何检测死代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37705520/