【问题标题】:How to deeply analyze Java switches over enumerations with SonarQube如何使用 SonarQube 深入分析 Java 切换枚举
【发布时间】:2013-10-16 08:52:42
【问题描述】:

对我来说,下面的 Java 代码是完全有效的,很好的风格:

enum Side { LEFT, RIGHT };
...
Side side = ...;
switch (side) {
case LEFT:
    // do something
    break;
case RIGHT:
    // do something
    break;
}

对于 SonarQube 的规则 SwitchLastCaseIsDefaultCheck,这还不够好,它需要一个默认情况。现在在这里,默认情况是多余的,因为枚举已被完全覆盖。

对于枚举,我希望看到一个测试来检查枚举是否被完全覆盖,如果没有被覆盖并且没有默认情况(Eclipse 可以做到这一点)。两者都应该没问题。事实上,完全覆盖枚举允许稍后在扩展枚举时发出编译时警告,而给出默认情况只会在运行时失败。

可选地,完全覆盖枚举和给出默认情况都可能触发无法访问代码的警告。

【问题讨论】:

  • 这里的确切问题是什么?
  • 为什么不在枚举中实现命令模式并在那里编写特定于枚举的代码?这样,您根本不需要 switch 语句,并且如果有人扩展该枚举(可能使用 UPDOWN)但忘记更新该开关(这正是声纳警告的原因,如果你有该规则有效)。
  • @Julien:问题是“如何使用 SonarQube 深入分析 Java 切换枚举?”
  • @Matthias:将代码放入枚举中巧妙地解决了添加枚举常量也应始终添加处理它的代码的问题。然而,这样做并不总是可行的,所以问题仍然存在。

标签: java enums switch-statement sonarqube


【解决方案1】:

我建议最好始终包含一个默认情况,该情况会引发适当的RuntimeException。这样,您就可以防止未来的开发人员在 enum 中添加内容而忘记更新 switch 语句。

【讨论】:

  • 这似乎是 Sonar 暗示的建议。然而,它并没有在编译时静态地保护我。即使在启动程序之前就可以静态确定问题,为什么我还需要运行时异常?
【解决方案2】:

Eclipse 是一个 IDE,它可以帮助您在此处使用选定的语言开发程序,在您的情况下它是 JAVA,它不会做任何未在语言中指定的事情,所以它不是 eclipse 的问题,这完全是关于语言的规范。

【讨论】:

  • 没有人在 Eclipse 中提出问题。相反,我明确提到了 Eclipse 作为如何正确分析问题的示例。
【解决方案3】:

事实证明,在提出这个问题三年后,我发现squid:SwitchLastCaseIsDefaultCheck 现在检查enum 的完整覆盖范围。可能已经有一段时间了,至少对于 Sonarqube 的 Java 插件的 4.4.0.8066,我可以确认这一点。这对我来说是一个非常令人满意的答案。

【讨论】: