这是findbugs的错误吗?

Is this a bug of findbugs?

我有一个包含如下代码的 jenkins 插件:

public int getLastBuildNumber() {
    if (project != null && project.getLastBuild() != null ) {
        return project.getLastBuild().getNumber();
    }
    return 0;
}

当我使用 mvn release:prepare release:perform -Dusername=myusername -Dpassword=mypassword 发布代码时,我收到一个错误 Possible null pointer dereference

这是 mvn findbugs:gui 的结果:

为什么说The return value from a method is dereferenced without a null check

我认为 project != null && project.getLastBuild() != null 是空检查,不是吗?

这是findbugs的bug吗?我该如何解决?或者我可以在发布我的 jenkins 插件时禁用 findbugs 吗?

您可以访问 here 获取完整代码。

除非您的 Project class 是不可变的或者(至少)getLastBuild() 返回的值是一个 final 字段,否则您的空检查是不够的。

这是因为,理论上,其他线程可能会在您的 return 语句之前调用 project.setLastBuild(null)

if (project != null && project.getLastBuild() != null) {
    // thread T does project.setLastBuild(null) here -- for whatever reason
    return project.getLastBuild().getNumber(); // NPE!
}

要做到这一点,您需要远离那些活动部件并制作您自己的本地副本(恕我直言,在这种情况下同步几乎不是一个选项):

LastBuild lastBuild = project != null ? project.getLastBuild() : null; // this only works as long as your project reference is final
return lastBuild != null ? lastBuild.getNumber() : 0;

或者,更好的是,利用 Java8 Optional 一次性执行所有必要的空值检查(隐式地):

return Optional.ofNullable(project)
    .map(Project::getLastBuild)
    .map(LastBuild::getNumber)
    .orElse(0);