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

发布于 2024-08-06 20:58:44 字数 1310 浏览 4 评论 0原文

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()

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

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

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

1. Regarding 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 Is it necesarry to follow this warning advice?

  A class which only has private constructors should be final

1.3 What is that supposed to mean?

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

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.Regarding FindBugs:

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());

where appCalendar is a static variable.

2.2 This code:

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

gives the warning:

Immediate dereference of the result of readLine()

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 was fixed when I replaced the code with:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青瓷清茶倾城歌 2024-08-13 20:58:44

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

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

这些文件位于 PMD 发行版的 rulesets 目录中。将 PMD 与 Eclipse 结合使用时,请检查自定义 PMD

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

只有私有构造函数的类应该是final的

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

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

1.3 这是什么意思?

“Dog”类的圈复杂度为 3(最高 = 17)

复杂度是方法中决策点的数量加上方法入口的1。决策点是“if”、“while”、“for”和“case labels”。一般来说,1-4 表示低复杂度,5-7 表示中等复杂度,8-10 表示高复杂度,11+ 表示非常高复杂度。

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

[...] 该指标仅在单个方法的上下文中才有意义。提及某个类的圈复杂度为 X 本质上是没有用的。

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

公众号 getAccount(){
   返回此帐户;
}

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

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

下次你发现自己的时候
读取copatic聚合
a 的循环复杂度值
类,确保你理解如何
该类包含许多方法。如果
总循环复杂度
一个类的值是 200——不应该
提出任何危险信号,直到您知道
方法计数。更重要的是,如果你
发现方法数还少
圈复杂度值为
高,你几乎总能找到
复杂性局限于方法

就在!

所以对我来说,这个 PMD 规则应该小心对待(实际上并没有多大价值)。

1.4 这个怎么样?我很想改变这一点,但目前我没有想到任何关于改变的事情:

将对象分配给 null 是一种代码味道。考虑重构。

不确定你对此有何不明白。

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

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

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

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

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

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.

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

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.

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 What is that supposed to mean?

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

The complexity is the number of decision points in a method plus one for the method entry. The decision points are 'if', 'while', 'for', and 'case labels'. Generally, 1-4 is low complexity, 5-7 indicates moderate complexity, 8-10 is high complexity, and 11+ is very high complexity.

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

[...] 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.

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;
}

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.

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.

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!

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

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 Is it really that bad to write to a static field, at some point later than its declaration? [...]

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 [...] Immediate dereference of the result of readLine()

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.

总以为 2024-08-13 20:58:44

这里有一些想法/答案

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

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

关于你的2.2,你是对的,通过空检查,你确信你不会有任何NullPointerException。我们永远不知道你的 BufferedReader 何时会阻塞/垃圾,这种情况并不经常发生(根据我的经验),但我们永远不知道硬盘驱动器何时崩溃。

Here some idea / answer

1.4 What is the reason to assign null to a object? If you reuse the same variable, there's not reason to set it to null before.

2.1 The reason about this warning, is to be sure that all your instance of the class Main have the same static fields. In your Main class, you could have
static Calendar appCalendar = Calendar.getInstance() ;

about your 2.2 you're right, with the null check, you are sure that you'll not have any NullPointerException. We never know when your BufferedReader can block/trash, this doesn't happen often (in my experience) but we never know when a hard drive crash.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文