我想使用FindBugs创建有关应用程序的报告。
我运行它并没有找到像这样的潜在错误:
public List<String> getListTrace(A object) {
String arg = object.getArg();
...
}
如果object为null,我的应用程序将会关闭。
为什么FindBugs不会发出警报?
答案 0 :(得分:2)
Findbugs不知道对象是否允许为null。您可以使用注释来告诉它:
import javax.annotation.Nullable;
...
public List<String> getListTrace(@Nullable A object) {
这告诉Findbugs(以及读取代码的人)可以将null作为参数传递给getListTrace。因此,如果你取消引用对象而不检查null,Findbugs会发出警告。
答案 1 :(得分:0)
该代码看起来没有错误。
如果您更改了代码以检查object
是否为空,您会怎么做?最合理的行动可能会抛出一个NullPointerException
,对吗?
这正是您的代码段的作用;它只是让java在访问方法时自动进行测试。
此函数不检查空指针不是错误。如果有人将空指针传递给你的函数并且没有准备好引发NullPointerException
,那就是错误。
答案 2 :(得分:0)
Findbug无法检测潜在的空指针访问。但是,如果在首选项中激活相应的编译器警告,Eclipse可以为潜在的空指针访问提供警告。
答案 3 :(得分: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 poit of view getListTrace()
方法可以。但是callSite
方法有一个错误。它显式检查其null
的参数,因此由于应用程序逻辑,它可以为null。然而,它后来传递给getListTrace()
,立即取消引用该论点。因此,您在getListTrace()
方法中有一个错误警告:
错误:在
中为getListTrace(FBNull$A)
FBNull.callSite(FBNull$A)
的非空参数传递了空值此方法调用为非null方法参数传递null值。要么将参数注释为应始终为非null的参数,要么分析表明它将始终被取消引用。
因此,如果您确实可以传递空值,则可以在呼叫站点上检测到它。