sonarqube可以集成findbug,pwd,lint等静态代码检查工具,提供统一的检查平台.
sonar代码检测的标准:
1、Reliability可靠性:低于A
可靠性比率的计算方法:
A = 0 Bug 最高等级A,表示代码无bug
B = at least 1 Minor Bug 代码只要有一个次要bug,等级就为B
C = at least 1 Major Bug 只要包含一个重要bug,等级将为C
D = at least 1 Critical Bug 只要有一个严重bug,等级评估为D
E = at least 1 Blocker Bug 只要有一个最高等级的阻断级别的bug,可靠性评估为E,最低级别。
2、Security安全性:低于A
安全度指标计算方法:
A = 0 Vulnerability 没有漏洞时,项目评估为最高级别A
B = at least 1 Minor Vulnerability 只要包含一个次要漏洞,项目评估为级别B
C = at least 1 Major Vulnerability 只要包含一个重要漏洞,项目评估为级别C
D = at least 1 Critical Vulnerability 只要包含一个严重漏洞,评估为D
E = at least 1 Blocker Vulnerability 只要包含一个阻断漏洞,项目评估为最低级别E
3、Maintainability可维护性:低于A
可维护性等级范围从A(非常好)到E(非常差)。 评级由技术债务比率的值决定,技术债务比率是将项目的技术债务与从零开始重写代码所需的成本进行比较。 A到D的默认值为0.05,0.1,0.2,0.5。任何超过0.5评级就为E。
4、Coverage覆盖率:新增覆盖率低于60%
Coverage
行覆盖和条件覆盖的混合。单元测试覆盖多少源代码。Coverage = (CT + CF + LC)/(2*B + EL)
其中 :
CT = conditions that have been evaluated to ‘true’ at least once至少有一次被判断为true的条件数
CF = conditions that have been evaluated to ‘false’ at least once 至少一次被判断为false的条件数
LC = covered lines = lines_to_cover uncovered_lines 已覆盖的行数
B = total number of conditions 条件总数
EL = total number of executable lines (lines_to_cover) 所有可执行的代码总行数
5、Duplicated Lines:新增代码重复行高于3%
其中 :重复率=重复行数/总行数*100
6、Complexity复杂度:高于10
以下关键词增加复杂性:if, for, while, case, catch, throw, return (不是方法的最后一个语句), &&, ||, ?
else, default, finally不增加复杂度
代码复杂度过高将难以理解、难以维护。
计算公式1:V(G)=E-N+2P。其中,E表示控制流图中边的数量,N表示控制流图中节点的数量,P图的连接组件数目(图的组件数是相连节点的最大集合)。因为控制流图都是连通的,所以P为1.
圈复杂度 代码状况 可测性 维护成本
1-10 清晰、结构化 高 低
11-20 复杂 中 中
21-30 非常复杂 低 高
>30 不可读 不可测 非常高
常遇到的问题:
坏味道,漏洞,bug,代码规范。
Bugs:
1.A "NullPointerException" could be thrown; "issue" is nullable here.
空指针异常.
2.Cast one of the operands of this addition operation to a "float".
不同类型的值做运算,需要统一成一种类型.
3.Use an "instanceof" comparison instead.
例如:RuntimeException.class.getName().equals(className);改成instanceof.
4.Use "BigDecimal.valueOf" instead.
new BigDecimal(teraBytes)改成valueOf.
Vulnerability:
1.Make tag a static final constant or non-public and provide accessors if needed.
public String tag;把tag变量变成静态常量或非公共常量,并在需要时提供访问器。
2.Use a logger to log this exception.
e.printStackTrace();改成logger.
3.Do something with the "boolean" value returned by "createNewFile".
public static File compressImage(){}返回值类型不对,改成boolean.
Code Smell:
1.Remove this unused "TAG" private field.
移除无用的自定义变量.
2.Rename this package name to match the regular expression '^[a-z]+(\.[a-z][a-z0-9]*)*$'.
包名书写要符合正则规范.
3.Add a nested comment explaining why this method is empty, throw an UnsupportedOperationException or complete the implementation.
无用的空方法,没有添加注释,说明用处.
4.Introduce a new variable instead of reusing the parameter "percent".
变量名重复使用.
5.Catch Exception instead of Throwable.
捕获异常而非直接抛出.
6.Add a private constructor to hide the implicit public one.
缺少私有构造函数.
7.This block of commented-out lines of code should be removed.
注释掉的代码块应该删除.
8.Change this "try" to a try-with-resources.
传统的try-catch-finally,当需要关闭的资源很多时,代码finally会很多,导致代码冗余.换成try-with的模式会使得代码简洁.