代码分析器:PMD &查找错误

2022-01-16 00:00:00 eclipse-plugin java eclipse findbugs pmd

1.关于 PMD:

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

1.1 How do I set the PMD checks, to ignore some of them, like "Variable name is too short, or too long", "Remove empty constructor, etc" - and if I do that, another warning appears that says the class must have some static methods. Basically, the class was empty, for later development, and I like to leave it that way for now.

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

1.2 Is it necesarry to follow this warning advice?

  A class which only has private constructors should be final

1.3 那应该是什么意思?

1.3 What is that supposed to mean?

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

1.4 这个呢?我很想改变这一点,但目前我没有想到任何改变:

1.4 What about this one? I would love to change this, but nothing crosses my mind at the moment regarding the change:

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

2.关于 FindBugs:

2.1 在声明之后的某个时间点写入静态字段真的有那么糟糕吗?以下代码给了我一个警告:

2.1 Is it really that bad to write to a static field, at some point later than its declaration? The following code gives me a warning:

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

其中 appCalendar 是一个静态变量.

where appCalendar is a static variable.

2.2 这段代码:

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

给出警告:

Immediate dereference of the result of readLine()

其中 objBRdr 是一个 BufferedReader(FileReader).会发生什么?readLine() 可以为空吗?代码嵌套在 while (objBRdr.ready()) 测试中,到目前为止,我在那里的问题为零.

where objBRdr is a BufferedReader(FileReader). What could happen? readLine() could be null? The code is nested in while (objBRdr.ready()) test, and so far, I have zero problems there.

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

Update1: 2.2 was fixed when I replaced the code with:

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

推荐答案

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

1.1 How do i set the PMD checks [...]

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

PMD stores rule configuration in a special repository referred to as the Ruleset XML file. This configuration file carries information about currently installed rules and their attributes.

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

These files are located in the rulesets directory of the PMD distribution. When using PMD with Eclipse, check Customizing PMD.

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

1.2 Is it necessary to follow this warning advice?

A class which only has private constructors should be final

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

All constructors always begin by calling a superclass constructor. If the constructor explicitly contains a call to a superclass constructor, that constructor is used. Otherwise the no-argument constructor is implied. If the no-argument constructor does not exist or is not visible to the subclass, you get a compile-time error.

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

So it's actually not possible to derive a subclass from a class whose every constructor is private. Marking such a class as final is thus a good idea (but not necessary) as it explicitly prevent subclassing.

1.3 这是什么意思?

1.3 What is that supposed to mean?

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

复杂度是方法中决策点的数量加上方法入口的数量.决策点是if"、while"、for"和case 标签".一般1-4为低复杂度,5-7为中等复杂度,8-10为高复杂度,11+为极高复杂度.

话虽如此,我只引用 聚合圈复杂度没有意义:

Having that said, I'll just quote some parts of Aggregate Cyclomatic complexity is meaningless:

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

[...] This metric only has meaning in the context of a single method. Mentioning that a class has a Cyclomatic complexity of X is essentially useless.

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

Because Cyclomatic complexity measures pathing in a method, every method has at least a Cyclomatic complexity of 1, right? So, the following getter method has a CCN value of 1:

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

从这个布吉方法很明显account 是 this 的一个属性班级.现在想象这个类有 15 个属性,并且每个属性都遵循典型的 getter/setter 范例,而这些是唯一可用的方法.这意味着该类有 30 个简单方法,每个方法的圈复杂度值为 1.则该类的聚合值为 30.

It’s clear from this boogie method that account is a property of this class. Now imagine that this class has 15 properties and follows the typical getter/setter paradigm for each property and those are the only methods available. That means the class has 30 simple methods, each with a Cyclomatic complexity value of 1. The aggregate value of the class is then 30.

这个值有什么意义吗,伙计?当然,随着时间的推移观看它可能会产生一些有趣的东西;然而,就其本身而言,作为一个总价值,它本质上是没有意义的.30 为类没有任何意义,30 代表一个方法不过也有一定的意义.

Does this value have any meaning, man? Of course, watching it over time may yield something interesting; however, on its own, as an aggregate value, it is essentially meaningless. 30 for the class means nothing, 30 for a method means something though.

下次你找到自己的时候阅读一个共济会聚合体a 的圈复杂度值上课,确保你明白如何该类包含许多方法.如果总圈复杂度一个类的值是 200——它不应该提出任何危险信号,直到您知道方法的计数.更重要的是,如果你发现方法计数还很低圈复杂度值为高,你几乎总能找到复杂性局限于方法.马上!

The next time you find yourself reading a copasetic aggregate Cyclomatic complexity value for a class, make sure you understand how many methods the class contains. If the aggregate Cyclomatic complexity value of a class is 200– it shouldn’t raise any red flags until you know the count of methods. What’s more, if you find that the method count is low yet the Cyclomatic complexity value is high, you will almost always find the complexity localized to a method. Right on!

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

So to me, this PMD rule should be taken with care (and is actually not very valuable).

1.4 这个呢?我很想改变这一点,但目前我没有想到任何改变:

1.4 What about this one? I would love to change this, but nothing crosses my mind at the moment regarding the change:

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

不知道你对这个有什么不明白.

Not sure what you don't get about this one.

2.1 在声明之后的某个时间点写入静态字段真的有那么糟糕吗?[...]

2.1 Is it really that bad to write to a static field, at some point later than its declaration? [...]

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

My guess is that you get a warning because the method contains an unsynchronized lazy initialization of a non-volatile static field. And because the compiler or processor may reorder instructions, threads are not guaranteed to see a completely initialized object, if the method can be called by multiple threads. You can make the field volatile to correct the problem.

2.2 [...] 立即取消引用 readLine() 的结果

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

If there are no more lines of text to read, readLine() will return null and dereferencing that will generate a null pointer exception. So you need indeed to check if the result is null.

相关文章