1

我已将 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 是可疑的

有没有人可以解决这个问题?

4

1 回答 1

4

问题是 Checker 框架假定Collectors.toList()返回一个List<@Nullable...>. 这是一个安全、保守的假设,但在您的上下文中,您需要List<@NonNull...>. Checker Framework 的类型推断目前太弱,无法推断出您想要的类型。

解决问题最干净的方法是更改Collectors.toList()​​为Collectors.<String>toList(). (写作 justString等价于@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);
  }
}
于 2016-12-06T19:00:26.223 回答