I am integrating checker framework to our project. One issue I get is the iterating.over.nullable
. I am not sure why I get this error since I validate the list using CollectionUtils.isEmpty()
before accessing the elements of the list.
The list item is Nullable
but as I understand, since I do the check before accessing, it should not raise the error. Appreciate if someone could point out what I am doing wrong. Below is the code. I get the error iterating.over.nullable
in line 4.
public List<MyCustomObject> map(Delivery delivery) {
List<MyCustomObject> delList = new ArrayList<>();
if (!CollectionUtils.isEmpty(delivery.getDeliveries())) {
for (MyCustomObject deliveries : delivery.getDeliveries()) {
//Processing code
}
}
return delList;
}
Thanks in advance.
The Nullness Checker has identified a genuine problem, and the best solution is not to suppress the warning. The problem might be in your code or in your annotations.
Problems like this, and their solutions, are discussed in the Checker Framework manual, in section Side effects, determinism, purity, and type refinement.
In the if
test, delivery.getDeliveries()
evaluated to a non-null and non-empty value. However, there is no guarantee that the second call in the for
loop also evaluates to a non-null and non-empty value.
Therefore, it is indeed possible that, in the for
loop, delivery.getDeliveries()
is null and a NullPointerException could occur at run time.
One approach is to extract the expression into a local variable:
Collection<MyCustomObject> allDeliveries = delivery.getDeliveries();
if (!CollectionUtils.isEmpty(allDeliveries)) {
for (MyCustomObject deliveries : allDeliveries) {
// Processing code
}
Another approach is to declare the getDeliveries()
method as @Deterministic
.