IntelliJ 不推断 Stream.collect() 类型结果

IntelliJ doesn't infer Stream.collect() type result

此代码适用于 Netbeans,但在 IntelliJ 上出错:

public static List<String> readFile(String file) throws IOException {
   Path path = Paths.get("src", file);
   Stream<String> lines = Files.lines(path);
   return lines.collect(Collectors.toList());
}

错误出现在 return 语句上,并指出需要 List<String>collect() 方法给出了 List<Object>。 看起来 Netbeans 能够理解必须将 Stream<String> 收集到 List<String> 而 IntelliJ 不是。

这里有什么问题?

编辑:按照建议,我将 IntelliJ 升级到最新版本 (14.1.1),并尝试通过终端用 javac 编译我的代码:它有效。问题一定出在我的 IntelliJ 配置中,但对我来说它看起来是正确的

会不会是您的 IntelliJ 未正确设置 Java 1.8?

Set the JDK for IntelliJ。它可能指向较旧的 Java 版本

为什么要手动创建 List<String>? “它有一个 API。” ;-)

根据您的需要修改代码段。

Path path = Paths.get("src", file);
Charset charset = Charset.defaultCharset();
List<String> lines = Files.readAllLines(path, charset);

编辑

查看您的 toList() 方法的签名。我相信它与那个有关。

如果像

private static List<Object> toList() {
    return null;
}

您在 IntelliJ 中收到了您发布的错误消息:Collector<? super String,Object,List<String>> in Stream cannot be applied to ListObject>。在 Netbeans 中类似。

如果像

static <T> Collector<T,?,List<T>> toList() {
    return null;
}

您在 IntelliJ 中收到错误 required: List<String> found: List<Object。而在 Netbeans 中它编译。

如果像

static Collector<? super String, Object, List<String>> toList() {
    return null;
}

你没有收到错误。

因此,正如已经提到的,它以某种方式链接到您的 toList()。知道 new Collector(T, A, R).

的类型参数会很有趣

您可以使用显式类型参数帮助编译器:

return lines.collect(Collectors.<String>toList());

这在以前是正确的,但现在为改进编译器类型推断所做的工作应该使这个类型参数变得不必要了。

据我所知,IntelliJ 在幕后使用 javac,所以你的编译错误有点奇怪。

也尝试直接在命令行中用javac编译你的文件,看看你是否有同样的错误。

如果是,那就尽快升级javac。如果不是,那么您的 IntelliJ 配置肯定有问题。您也可以将 IntelliJ 升级到最新的 14.1.1 版本。

我解开了谜团:在File Menu->Project Structure中,将Project Language Level改为8.0 - Lambdas, type annotations etc.