2

SonarQube 认为以下代码违反了规则 fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER(注意,代码示例是简化的,不符合逻辑):

class Foo {

   boolean baz;

   boolean foo() { 
      return bar() && baz==Baz.VALUE; //Violation of fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER
   }

   boolean bar() { 
      return baz == Baz.VALUE_2; 
   }

}

enum Baz {
    VALUE, VALUE2
}

性能 - 方法以次优方式在条件中对表达式进行排序 (fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER)

此方法构建一个条件表达式,例如,在 if 或 while 语句中,其中表达式既包含简单的局部变量比较,也包含方法调用的比较。表达式对这些进行排序,以便方法调用位于简单的局部变量比较之前。这会导致方法调用在不需要的条件下执行,因此可能会导致大量代码白白执行。通过对表达式进行排序,使包含局部变量条件的简单条件在前,您可以消除这种浪费。这假定方法调用没有副作用。如果该方法确实有副作用,最好将这些调用从条件中拉出并首先执行它们,将值分配给局部变量。

我认为规则实现查看实际表达式内部是合理的,如果内容是值检查,则不会触发违规。

这是一个错误还是我错过了什么?

4

1 回答 1

1

你几乎已经在你的问题中给出了答案:

这会导致方法调用在不需要的条件下执行,因此可能会导致大量代码白白执行。通过对表达式进行排序,使包含局部变量条件的简单条件在前,您可以消除这种浪费。

FB-Contrib 想让你把表达式转过来:

boolean foo() { 
    return baz==Baz.VALUE && bar();
}

这种方式,bar()只有在 时才需要执行baz==Baz.value。当然,这是编译器或 JVM 可能会优化的东西,所以它会归结为一个微基准来确定这种预防措施是否真的有必要。

但它在语法层面上是有意义的,因为调用方法通常比值检查更昂贵。因此,您无需查看方法内部即可知道这一点。无论如何,对编译器/JVM 的内联行为的任何猜测都可能是错误的。

于 2017-03-21T20:41:31.827 回答