2

我想使用 FindBugs 创建有关应用程序的报告。

我运行它并没有发现像这样的潜在错误:

public List<String> getListTrace(A object) {

    String arg = object.getArg();
    ...
}

如果对象为空,我的应用程序将关闭。

为什么 FindBugs 不发出警报?

4

4 回答 4

2

Findbugs 不知道 object 是否允许为空。您可以通过使用注释来告诉它:

import javax.annotation.Nullable;
...
public List<String> getListTrace(@Nullable A object) {

这告诉 Findbugs(和阅读代码的人)可以将 null 作为参数传递给 getListTrace。因此,如果您取消引用对象而不检查 null,Findbugs 会警告您。

于 2012-06-07T20:39:18.733 回答
0

该代码看起来没有错误。

如果您更改代码以检查是否object为空,您会怎么做?最合理的动作可能是抛出一个NullPointerException,对吧?

这正是您的代码片段所做的;它只是让java在访问方法时自动进行测试。

此函数不检查空指针不是错误。如果有人将空指针传递给您的函数并且没有准备好引发NullPointerException.

于 2012-06-07T10:16:15.390 回答
0

Findbug 无法检测潜在的空指针访问。但是,如果您在首选项中激活相应的编译器警告,Eclipse 会针对潜在的空指针访问向您发出警告。

于 2012-06-07T10:49:44.767 回答
0

在这种情况下提出错误报告会导致非常大的噪音。您会在完全正确的代码中收到数千条不相关的错误消息。实际上 FindBugs 做了更聪明的事情。如果它发现该方法在没有进行空检查的情况下取消引用该参数,它会在内部将此方法参数标记为@Nonnull. 如果您有TimK与此相矛盾的明确注释(如答案),您将收到警告。否则 FindBugs 假定没有人使用此方法和可能为空的参数。当有人实际这样做时,您会在呼叫站点上收到相应的警告。这是一个例子:

import java.util.Collections;
import java.util.List;

public class FBNull {
    static class A {
        String getArg() {
            return "str";
        }
    }

    public static List<String> getListTrace(A object) {
        String arg = object.getArg();
        return Collections.singletonList(arg);
    }

    public void callSite(A a) {
        if (a == null) {
            System.out.println("a is null");
        }
        System.out.println(getListTrace(a)); // NP_NULL_PARAM_DEREF 
    }
}

从 FindBugs 的观点来看getListTrace()方法是可以的。但是该callSite方法有一个错误。它显式检查其参数null,因此由于应用程序逻辑,它可能为空。但是,它稍后被传递给getListTrace()which 立即取消引用该参数。因此,您在方法中有一个错误警告getListTrace()说:

getListTrace(FBNull$A)错误:为in的非空参数传递空值FBNull.callSite(FBNull$A)

此方法调用为非空方法参数传递空值。要么将参数注释为应始终为非空的参数,要么分析表明它将始终被取消引用。

因此,如果您实际上可以传递空值,则可以在调用站点上检测到它。

于 2015-09-23T06:21:15.377 回答