代码分析仪:PMD& FindBugs的

时间:2009-10-10 21:43:11

标签: java eclipse eclipse-plugin findbugs pmd

1。关于PMD:

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

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

  A class which only has private constructors should be final

1.3那是什么意思?

 The class 'Dog' has a Cyclomatic Complexity of 3 (Highest = 17)

1.4这个怎么样?我很乐意改变这一点,但目前没有任何关于改变的事情在我脑海中浮现:

Assigning an Object to null is a code smell. Consider refactoring.

2.Regarding FindBugs:

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

Main.appCalendar = Calendar.getInstance();
Main.appCalendar.setTimeInMillis(System.currentTimeMillis());

其中appCalendar是一个静态变量。

2.2此代码:

strLine = objBRdr.readLine().trim();

发出警告:

Immediate dereference of the result of readLine()

其中objBRdrBufferedReader(FileReader)。怎么会发生什么? readLine()可能为空? 代码嵌套在while (objBRdr.ready())测试中,到目前为止,我没有问题。

当我用以下代码替换代码时,

Update1:​​2.2被修复了:

strLine = objBRdr.readLine();
    if (strLine != null) {
        strLine = strLine.trim();
    }

2 个答案:

答案 0 :(得分:9)

  

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

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

这些文件位于PMD发行版的rulesets目录中。在Eclipse中使用PMD时,请检查Customizing PMD

  

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

A class which only has private constructors should be final

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

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

  

1.3这是什么意思?

The class 'Dog' has a Cyclomatic Complexity of 3 (Highest = 17)

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

话虽如此,我只会引用Aggregate Cyclomatic complexity is meaningless的某些部分:

  

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

     

因为Cyclomatic复杂性测量   在一个方法中路径,每个方法都有   至少一个Cyclomatic复杂度为1,   对?所以,以下的getter方法   CCN值为1:

public Account getAccount(){
   return this.account;
}
     

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

     

这个值有什么意义吗,伙计?   当然,随着时间的推移观看它可能   产生有趣的东西;然而,   它本身就是一个总价值   基本上没有意义。 30为   class意味着什么,30表示方法   虽然意味着什么。

     

下次你发现自己   阅读copasetic聚合   a的循环复杂度值   上课,确保你明白了   该类包含的许多方法。如果   聚合循环复杂性   一个类的值是200-它不应该   举起任何红旗,直到你知道   计数方法。更重要的是,如果你   发现方法计数还很低   Cyclomatic复杂度值是   高,你几乎总能找到   复杂性本地化为方法。   好吧!

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

  

1.4这个怎么样?我很乐意改变这一点,但目前没有任何关于改变的事情在我脑海中浮现:

Assigning an Object to null is a code smell. Consider refactoring.

不确定你没有得到这个。

  

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

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

  

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

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

答案 1 :(得分:2)

这里有一些想法/答案

1.4为对象分配null的原因是什么?如果重复使用相同的变量,则没有理由在之前将其设置为null。

2.1此警告的原因是为了确保Main类的所有实例都具有相同的静态字段。在您的Main课程中,您可以拥有 static Calendar appCalendar = Calendar.getInstance();

关于你的2.2你是对的,使用空检查,你确定你不会有任何NullPointerException。我们永远不知道您的BufferedReader何时可以阻止/丢弃,这种情况不会经常发生(根据我的经验),但我们永远不知道硬盘何时崩溃。