代码分析器:PMD和FindBugs

hyp*_*ube 7 java eclipse eclipse-plugin findbugs pmd

1.关于PMD:

1.1如何设置PMD检查,忽略其中的一些,例如"变量名太短或太长","删除空构造函数等" - 如果我这样做,会出现另一个警告,说该类必须有一些静态的方法.基本上,这个课程是空的,以便以后开发,我现在想把它留下来.

1.2遵循此警告建议是否必要?

  A class which only has private constructors should be final
Run Code Online (Sandbox Code Playgroud)

1.3那是什么意思?

 The class 'Dog' has a Cyclomatic Complexity of 3 (Highest = 17)
Run Code Online (Sandbox Code Playgroud)

1.4这个怎么样?我很乐意改变这一点,但目前关于变化的事情并没有让我想到:

Assigning an Object to null is a code smell. Consider refactoring.
Run Code Online (Sandbox Code Playgroud)

2.关于FindBugs:

2.1写入静态字段是否真的那么糟糕,比它的声明要晚一些?以下代码给了我一个警告:

Main.appCalendar = Calendar.getInstance();
Main.appCalendar.setTimeInMillis(System.currentTimeMillis());
Run Code Online (Sandbox Code Playgroud)

哪里appCalendar是静态变量.

2.2此代码:

strLine = objBRdr.readLine().trim();
Run Code Online (Sandbox Code Playgroud)

发出警告:

Immediate dereference of the result of readLine()
Run Code Online (Sandbox Code Playgroud)

这里objBRdr是一个BufferedReader(FileReader).怎么会发生什么?readLine()可能是空的?代码嵌套在while (objBRdr.ready())测试中,到目前为止,我没有问题.

当我用以下代码替换代码时,Update1:​​2.2被修复了:

strLine = objBRdr.readLine();
    if (strLine != null) {
        strLine = strLine.trim();
    }
Run Code Online (Sandbox Code Playgroud)

Pas*_*ent 9

1.1如何设置PMD检查[...]

PMD将规则配置存储在称为规则集XML文件的特殊存储库中.此配置文件包含有关当前安装的规则及其属性的信息.

这些文件位于rulesetsPMD分发的目录中.在Eclipse中使用PMD时,请检查自定义PMD.

1.2是否有必要遵循此警告建议?

A class which only has private constructors should be final
Run Code Online (Sandbox Code Playgroud)

所有构造函数总是从调用超类构造函数开始.如果构造函数显式包含对超类构造函数的调用,则使用该构造函数.否则暗示无参数构造函数.如果无参数构造函数不存在或子类不可见,则会出现编译时错误.

因此,实际上不可能从每个构造函数都是私有的类派生一个子类.因此,标记这样的类final是一个好主意(但不是必需的),因为它明确地阻止了子类化.

1.3那是什么意思?

The class 'Dog' has a Cyclomatic Complexity of 3 (Highest = 17)
Run Code Online (Sandbox Code Playgroud)

复杂性是方法中的决策点数加上方法条目的决策点数.决策点是'if','while','for'和'case labels'.通常,1-4是低复杂度,5-7表示中等复杂度,8-10表示高复杂度,11 +是非常高复杂度.

话虽如此,我只是引用Aggregate Cyclomatic复杂性的某些部分是没有意义的:

[...]此指标仅在单个方法的上下文中有意义.提到一个类具有X的Cyclomatic复杂性本质上是无用的.

由于Cyclomatic复杂度测量方法中的路径,每个方法至少具有1的Cyclomatic复杂度,对吧?因此,以下getter方法的CCN值为1:

public Account getAccount(){
   return this.account;
}
Run Code Online (Sandbox Code Playgroud)

从这个boogie方法中account可以清楚地看出,这是该类的一个属性.现在假设这个类有15个属性,并遵循每个属性的典型getter/setter范例,这些是唯一可用的方法.这意味着该类有30个简单方法,每个方法的Cyclomatic复杂度值为1.该类的聚合值为30.

这个价值有什么意义吗,伙计?当然,随着时间的推移观看可能会产生一些有趣的东西 然而,作为一个总价值,它本身就没有意义.班级30意味着什么,30方法意味着什么.

下次当您发现自己正在读取类的copasetic聚合Cyclomatic复杂度值时,请确保您了解该类包含的方法数量.如果一个类的聚合Cyclomatic复杂度值是200-它应该不会引发任何红色标记,直到你知道方法的数量.更重要的是,如果您发现方法计数较低但Cyclomatic复杂度值很高,您几乎总会发现本地化为方法的复杂性.对吧!

所以对我来说,这个PMD规则应该小心谨慎(实际上并不是很有价值).

1.4这个怎么样?我很乐意改变这一点,但目前关于变化的事情并没有让我想到:

Assigning an Object to null is a code smell. Consider refactoring.
Run Code Online (Sandbox Code Playgroud)

不确定你没有得到这个.

2.1写入静态字段是否真的那么糟糕,比它的声明要晚一些?[...]

我的猜测是你得到一个警告,因为该方法包含非易失性静态字段的非同步延迟初始化.并且因为编译器或处理器可能重新排序指令,所以如果多个线程可以调用该方法,则不保证线程看到完全初始化的对象.您可以使字段为volatile以纠正问题.

2.2 [...] Immediate dereference of the result of readLine()

如果没有更多的文本行要读取,readLine()将返回null并解除引用,这将生成空指针异常.所以你确实需要检查结果是否为null.