切换不间断

时间:2011-12-19 16:02:46

标签: java switch-statement findbugs

我有一些switch语句,如下所示。请注意,没有休息。 Findbugs仅在第二个案例陈述中报告错误。 错误是:在一个案例落入下一个案例的地方找到切换语句。

switch(x) {

    case 0:
        // code

    case 1:
        // code

    case 2:
        // code
}

6 个答案:

答案 0 :(得分:70)

Findbugs正在抨击,如果第一个中有任何代码,那么从一个case到另一个case的下降通常不是一个好主意(尽管有时它可以用来产生良好的效果)。因此,当它看到第二个break而没有switch (foo) { case 0: doSomething(); case 1: doSomethingElse(); default: doSomeOtherThing(); } 时,会报告错误。

例如:

foo

这是完全有效的Java,但它可能不符合作者的意图:如果0doSomething,则所有三个函数{{1} },doSomethingElsedoSomeOtherThing运行(按此顺序)。如果foo1,则仅运行doSomethingElsedoSomeOtherThing。如果foo是任何其他值,则仅运行doSomeOtherThing

相反:

switch (foo) {
    case 0:
        doSomething();
        break;
    case 1:
        doSomethingElse();
        break;
    default:
        doSomeOtherThing();
        break;
}

此处,只会运行其中一个函数,具体取决于foo的值。

由于忘记break是一个常见的编码错误,Findbugs等工具会为你标记它。

有一个常见的用例,你在没有干预代码的行中有多个case语句:

switch (foo) {
    case 0:
    case 1:
        doSomething();
        break;
    case 2:
        doSomethingElse();
        break;
    default:
        doSomeOtherThing();
        break;
}

在那里,如果doSomethingfoo 0,我们希望致电1。大多数工具都不会将此标记为可能的编码错误,因为case 0之前的case 1中没有代码,这是一种相当常见的模式。

答案 1 :(得分:4)

我把这些写成评论,但后来却看不到。我正在把它们变成一个答案。这实际上是T.J.Crowder's answer的扩展。

您可以找到导致Findbugs报告错误here的相关规则。

您可以通过创建包含以下内容的xml文件来阻止Findbugs报告此类错误,例如filter.xml并使用-exclude filter.xml选项运行该工具。请参阅filters on Findbugs

<FindBugsFilter>
  <Match>
    <Bug category="PERFORMANCE" />
  </Match>
</FindBugsFilter>

答案 2 :(得分:3)

切换漏洞属于“狡猾代码”的Findbugs类别。我认为它只标记switch语句中第一次出现的连贯,以减少错误消息的数量。

答案 3 :(得分:2)

如果没有中断,它们会相互掉落,所以如果x == 0你将遍历每个case语句块中的所有代码。 Findbugs可能是错误的错误,或者它可能是没有中断的错误条件,即case 0中的某些内容会导致case 1中的某些内容中断。

如果没有确切的代码和错误,我无法进一步提供帮助。故意缺乏休息吗?

答案 4 :(得分:2)

通常,错误分析工具不喜欢代码中的漏洞,因为在大多数情况下,用户只是忘记编写中断。

我不知道是否有办法通过 FindBugs 专门禁用警告,但 Checkstyle 工具会识别特殊注释,例如 / * fallthrough * / 假设用户确实希望执行以下代码。发表这种评论也可以提高可读性。 http://checkstyle.sourceforge.net/config_coding.html#FallThrough

Java代码约定还提到了使用fallthrough注释。 http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-142311.html

答案 5 :(得分:0)

如果您的案件没有中断,一旦案件触发,开关将经历所有案件,直到它找到案件的中断或结束。如果你有默认情况,如果你的开关值 foo 与任何其他情况不匹配,它将触发。