我有一些switch语句,如下所示。请注意,没有休息。 Findbugs仅在第二个案例陈述中报告错误。 错误是:在一个案例落入下一个案例的地方找到切换语句。
switch(x) {
case 0:
// code
case 1:
// code
case 2:
// code
}
答案 0 :(得分:70)
Findbugs正在抨击,如果第一个中有任何代码,那么从一个case
到另一个case
的下降通常不是一个好主意(尽管有时它可以用来产生良好的效果)。因此,当它看到第二个break
而没有switch (foo) {
case 0:
doSomething();
case 1:
doSomethingElse();
default:
doSomeOtherThing();
}
时,会报告错误。
例如:
foo
这是完全有效的Java,但它可能不符合作者的意图:如果0
是doSomething
,则所有三个函数{{1} },doSomethingElse
和doSomeOtherThing
运行(按此顺序)。如果foo
为1
,则仅运行doSomethingElse
和doSomeOtherThing
。如果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;
}
在那里,如果doSomething
为foo
或 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 与任何其他情况不匹配,它将触发。