每个循环被 PMD 标记为 UR 异常的 Java

我想确认这是否是PMD上的错误?如果是,我如何提交票证。

    public static void main(final String[] args) {
        for (final String string : args) {
            string.getBytes(); //UR Anomaly
        }
        for (int i = 0; i < args.length; i++) {
            args[i].getBytes();
        }
    }

第 1-3 行被标记为 UR 异常,而重写它以使用局部变量进行迭代是可以的。

希望消除尽可能多的PMD违规,但是必须诉诸旧的循环构造作为解决方法是不方便的。

虽然有争议,但我不希望禁用此规则,因为我发现DD和DU异常标记很有用。


答案 1

看来您在PMD中遇到了一个错误。Dataflow异常分析规则似乎没有捕获所有可能的变量定义(此处找到的另一个示例)。UR代表“未定义的引用”,这显然是不正确的。

那么,你能做些什么呢?

由于问题似乎主要影响规则的 UR 部分,因此您可以禁用它并继续使用 DU 和 DD 部分。您需要一个相当新版本的PMD来执行此操作。在规则集文件中,按如下方式禁止显示 UR 结果:

<rule ref="rulesets/java/controversial.xml/DataflowAnomalyAnalysis">
    <properties>
        <property name="violationSuppressRegex" value="^Found 'UR'-anomaly.*"/>
    </properties>
</rule>

更新:对于 PMD 6.+,规则引用已更改(感谢 ZuziaKru):

<rule ref="category/java/errorprone.xml/DataflowAnomalyAnalysis">
    <properties>
        <property name="violationSuppressRegex" value="^Found 'UR'-anomaly.*"/>
    </properties>
</rule>

在我看来,整个UR检查有点过头了,因为编译器不会接受未定义的引用。如今,运行编译器不再是一件大事。


答案 2

请参阅,适当的PMD规则数据流异常分析不断被认为是有争议的。我个人在几乎完全疯狂地检测几乎任何类型的异常时抓住了它:

  • 任何内联声明都会导致 UR 异常警报。这包括在循环作用域中定义的变量。for
  • 如果在循环范围之外定义了变量,并且其值在某个局部作用域结束之前在循环内发生更改,则通常会发出 DU 异常警报。
  • DD 异常通常与检测到错误的 UR 或 DU 同时报告。此外,如果我们在循环之前设置变量,然后在循环内更新其值(用于下一次迭代),则可能会报告它。即使在规则描述中,也会引用此异常,使其不那么相关。

因此,在我看来,完全关闭这个错误规则是值得的。