代码分析器:PMD和FindBugs

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.关于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()可能为null? 代码嵌套在while (objBRdr.ready())测试中,到目前为止,我没有问题。

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

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

1.1如何设置PMD检查[…]

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

这些文件位于PMD分发的rulesets目录中。 在Eclipse中使用PMD时,请选中自定义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复杂性的某些部分是没有意义的 :

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

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

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

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

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

下次当您发现自己正在读取类的copasetic聚合Cyclomatic复杂度值时,请确保您了解该类包含的方法数量。 如果一个类的聚合Cyclomatic复杂度值是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并解除引用将生成空指针exception。 所以你确实需要检查结果是否为null。

这里有一些想法/答案

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

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

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