在使用 @EnsuresNonNullIf验证方法时出现的空指针解引用错误
NullAway在下面这段代码中的 place.getGeographicLocation().getValue().getGeoJson().getCoordinates() 链的所有部分都报告了解引用错误,尽管它已经通过传递给 hasValidGeoJsonCoordinates 进行验证。我在验证方法中添加了 @EnsuresNonNullIf 注释,但似乎并不起作用。这是一个缺陷吗?还是对NullAway来说太复杂,无法处理?
Using ErrorProne 2.48.0、Nullaway 0.13.1、Java 21
private @Nullable String getCoordinate(int index) {
return getPlaces().stream()
.filter(this::hasValidGeoJsonCoordinates)
.map(place -> place.getGeographicLocation().getValue().getGeoJson().getCoordinates().get(index))
.filter(Objects::nonNull)
.map(Object::toString)
.findFirst()
.orElse(null);
}
@EnsuresNonNullIf(expression = {"#1", "#1.geographicLocation", "#1.geographicLocation.value", "#1.geographicLocation.value.geoJson", "#1.geographicLocation.value.geoJson.coordinates"}, result = true)
private boolean hasValidGeoJsonCoordinates(@Nullable Place place) {
return nonNull(place)
&& nonNull(place.getGeographicLocation())
&& nonNull(place.getGeographicLocation().getValue())
&& nonNull(place.getGeographicLocation().getValue().getGeoJson())
&& isNotEmpty(place.getGeographicLocation().getValue().getGeoJson().getCoordinates())
&& place.getGeographicLocation().getValue().getGeoJson().getCoordinates().size() > 1;
}
解决方案
NullAway的记忆力有点短。
当你使用一个 Stream 时,NullAway会把 filter 和 map 当作两个彼此不交谈的人。尽管 filter 已证明数据是安全的,map 仍然没收到这条信息。
使用for循环。将所有逻辑都放在一个块中时,NullAway在跟踪逻辑方面要好得多。
private @Nullable String getCoordinate(int index) {
for (Place place : getPlaces()) {
if (hasValidGeoJsonCoordinates(place)) {
// NullAway "sees" the check here and stays quiet
return place.getGeographicLocation().getValue().getGeoJson().getCoordinates().get(index);
}
}
return null;
}
如果你一定要在Stream中继续,可以把所有那些“获取”逻辑放在检查之后的单个 .map() 或 .flatMap() 里面,这样NullAway就不会丢失线索。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。