7

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()可以为空吗?代码嵌套在while (objBRdr.ready())测试中,到目前为止,我在那里的问题为零。

Update1:​​当我将代码替换为以下内容时,2.2 已修复:

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

2 回答 2

9

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

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

这些文件位于rulesetsPMD 分发的目录中。将 PMD 与 Eclipse 一起使用时,请选中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 标签”。一般来说,1-4是低复杂度,5-7表示中等复杂度,8-10是高复杂度,11+是非常高复杂度。

话虽如此,我将仅引用Aggregate Cyclomatic complex的某些部分是没有意义的:

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

因为圈复杂度衡量方法中的路径,所以每个方法的圈复杂度至少为 1,对吧?因此,以下 getter 方法的 CCN 值为 1:

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

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

这个值有什么意义吗,伙计?当然,随着时间的推移观看它可能会产生一些有趣的东西。然而,就其本身而言,作为一个聚合值,它本质上是没有意义的。30 表示类没有任何意义,但 30 表示方法意味着一些东西。

下次您发现自己在阅读类的 copasetic 聚合圈复杂度值时,请确保您了解该类包含多少方法。如果一个类的总圈复杂度值为 200——在您知道方法的数量之前,它不应该引发任何危险信号。更重要的是,如果您发现方法计数低但圈复杂度值高,您几乎总是会发现复杂度局限于方法。对了!

所以对我来说,这个 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 并且取消引用将生成空指针异常。所以你确实需要检查结果是否为空。

于 2009-10-10T23:26:05.280 回答
2

这里有一些想法/答案

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

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

关于你的 2.2,你是对的,通过空值检查,你确定你不会有任何 NullPointerException。我们永远不知道您的 BufferedReader 何时可以阻止/垃圾,这并不经常发生(根据我的经验),但我们永远不知道硬盘何时崩溃。

于 2009-10-10T22:11:51.987 回答