我有一个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的错误吗?我该如何解决?或者我可以在发布我的jenkins插件时禁用findbugs吗?
您可以访问here获取完整代码。
答案 0 :(得分:3)
除非Project
类是不可变的或(至少)getLastBuild()
返回的值是final
字段,否则您的空值检查是不够的。
这是因为,理论上,其他一些主题可能会在project.setLastBuild(null)
声明之前调用return
:
if (project != null && project.getLastBuild() != null) {
// thread T does project.setLastBuild(null) here -- for whatever reason
return project.getLastBuild().getNumber(); // NPE!
}
为了使这个子弹证明,您需要远离那些移动部件并制作您自己的本地副本(在这种情况下,同步几乎不是一个选项,imho):
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);