SonarQube - 布尔逻辑正确性 -

时间:2016-09-02 17:11:14

标签: java sonarqube boolean-expression

我的方法 matches1()上的逻辑表达式有问题。

问题

SonarQube告诉我有一个错误: (expectedGlobalRule == null && actual != null)

  

SonarQube:   更改此条件,以便它不总是评估为   “真正”。       条件不应无条件地评估为“TRUE”或“FALSE”

我实际上是在做这个逻辑,以避免我的“块被执行”中的 NPE

我的代码

matches1()

private boolean matches1(GbRule actual, GbRule expected) {
     if(actual == null && expected == null) {
        return true;
     } else if((expected == null && actual != null) || (expected != null && actual == null)) {
        return false;
     } else {
       //Block to be executed
     }
}

我颠倒了逻辑,看看SonarQube会告诉我什么,他并没有抱怨它。 matches2()

private boolean matches2(GbRule actual, GbRule expected) {
      if(actual == null && expected == null) {
         return true;
      } else if(expected != null && actual != null)  {
         //Block to be executed
      } else {
         return false;
      }
}

问题

  1. 问题出在我的布尔逻辑中,还是SonarQube丢失了 他的想法?
  2. 如果问题出在sonarQube内,我该如何解决呢?

3 个答案:

答案 0 :(得分:6)

问题在于你的逻辑。让我们一点一点地说:

 if(actual == null && expected == null) {
    return true;

此时如果两个变量都是null,那么我们就不再使用该方法了。因此,如果我们得到更多,那么至少其中一个是非空的。

此时可行的选择是:

  • actual = null,expected = non-null

  • actual =非null,expected = null

  • actual =非null,expected = non-null

现在,让我们看看下一段代码:

 } else if((expected == null && actual != null) 

我们已经知道这两个变量都不能是null,所以只要我们知道expected == null,就不需要测试actual != null。事实证明,我们已经做到了这一点。因此,actual != null始终为真,这就是提出问题的原因。

修改

这意味着您的代码可以归结为:

private boolean matches1(GbRule actual, GbRule expected) {
  if(actual == null && expected == null) {
    return true;
  } else if(actual == null || expected == null) {
    return false;
  } 

  //Block to be executed
}

请注意,不需要else&删除它使代码更容易阅读。

答案 1 :(得分:3)

即使代码正确;严肃地说,这会让我的眼睛受伤。事情是:阅读很难。这种嵌套条件是首先不应该写的东西。

如果你无法避免;至少将它重构为像

这样的东西
private boolean areActualAnedExpectedBothNull(args ...) {
  return actual == null && expectedGlobalRule == null;
}

请注意;你可以大大简化你的代码:

if (areActualAnedExpectedBothNull(actual, expected)) {
  return true;
}
if (actual == null) {
  return false;
}

if (expected == null) {
  return false;
}

do your thing ...

并在您的其他代码中使用此类方法。当然,你做了很多单元测试;可能有覆盖率测量;只是为了确保你的测试真正通过这个迷宫测试所有可能的路径。

但正如所说;你最好退一步思考是否有办法避免首先编写这样的代码。

布尔值的典型答案,以及OO编程中的if / else链是多态。所以不要问一下它的状态;你转向接口/抽象类;并有不同的实现。然后你有一个工厂为你提供所需的实施;然后你只需要调用方法;不再需要if / else / whatever。

如果你不知道我在说什么 - 请注意这些videos;特别是第二个!

答案 2 :(得分:-3)

问题在于SonarQube。

有关忽略该问题的详情,请参阅此文章:https://www.bsi-software.com/en/scout-blog/article/ignore-issues-on-multiple-criteria-in-sonarqube.html

您可以将其设置为忽略该文件中的错误。

它的要点是

  

打开设置(SonarQube常规设置或项目设置)和   选择排除类别。切换到问题排除和   向下滚动到“忽略多个标准上的问题”。设置鱿鱼:S00112   作为规则键模式和** / * Activator.java作为文件路径模式。

您需要将规则键模式更改为与您的代码违反规则相关联的模式,并将文件模式更改为.java文件的路径。