Метод сбора 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);
  }
}
Другие вопросы по тегам