2016-12-06 28 views
1

我已经介绍了检查框架v2.1.6到java8项目,并修复了所有NULL的含量的错误,但我坚持以下错误Java的收集方法与检查框架不兼容

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> 

以下(简化)示例代码通过使结果@Nullable引发错误

List<String> strings = new ArrayList<>(); 
strings.add("test"); 
List<String> collectedStrings = strings.stream().collect(Collectors.toList()); 
collectedStrings.forEach(System.out::println); 

现在,我可以解决此

List<@Nullable String> collectedStrings = strings.stream().collect(Collectors.toList()); 

但是,这只能将错误级联到下一次调用,现在认为collectStrings是可疑的

有没有人有一个很好的解决这个问题?

+0

我想你需要提供明确的类型参数给Collectors.toList()调用。似乎类型推断再次失败。但我不确定,因为我不熟悉Checker。 – glee8e

回答

4

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

解决问题最简单的方法是将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); 
    } 
}