Метод сбора Java несовместим с платформой Checker
Я ввел Checker Framework v2.1.6 в проект java8 и исправил все ошибки обнуления, но застрял на следующей ошибке
Main.java:52: error: [assignment.type.incompatible] incompatible types in assignment.
List<String> collectedStrings = strings.stream().collect(Collectors.toList());
^
found : @Initialized @NonNull List<@Initialized @Nullable Object>
required: @UnknownInitialization @Nullable List<@Initialized @NonNull String>
Следующий (упрощенный) пример кода выдает ошибку
List<String> strings = new ArrayList<>();
strings.add("test");
List<String> collectedStrings = strings.stream().collect(Collectors.toList());
collectedStrings.forEach(System.out::println);
Теперь я могу обойти это, сделав результат @Nullable
List<@Nullable String> collectedStrings = strings.stream().collect(Collectors.toList());
Но это только каскадирует ошибку на следующий вызов, который теперь думает, что collectStrings является подозрительным
У кого-нибудь есть хорошая работа для этого?
1 ответ
Проблема в том, что Checker Framework предполагает, что Collectors.toList()
возвращает List<@Nullable...>
, Это безопасное, консервативное предположение, но в вашем контексте вы хотите List<@NonNull...>
, Вывод типа Checker Framework в настоящее время слишком слаб, чтобы вывести нужный вам тип.
Самый чистый способ решить проблему - это изменить Collectors.toList()
в Collectors.<String>toList()
, (Пишу только String
эквивалентно @NonNull String
.)
Альтернативой является подавление предупреждения, написав @SuppressWarnings("nullness")
в задании.
Код ниже показывает все эти возможности.
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.checkerframework.checker.nullness.qual.Nullable;
public class CollectorsToList {
void m(List<String> strings) {
Stream<String> s = strings.stream();
// This works:
List<String> collectedStrings1 = s.collect(Collectors.<String>toList());
// This works:
List<@Nullable String> collectedStrings2 = s.collect(Collectors.toList());
// This works:
@SuppressWarnings("nullness")
List<String> collectedStrings3 = s.collect(Collectors.toList());
// This assignment issues a warning due to incompatible types:
List<String> collectedStrings = s.collect(Collectors.toList());
collectedStrings.forEach(System.out::println);
}
}