为什么相同的代码在 Eclipse 中有效,但在 IntelliJ 中甚至无法编译

Thr*_*ion 4 eclipse intellij-idea java-8 intellij-14

这里有 2 个代码片段,它们应该返回与我HashMapmap factory. 但是第二个代码片段不能在 IntelliJ 中编译。这两个代码在 Eclipse 中都可以正常工作。

System.out.println方法需要一些可以调用的东西toString,但是在 IntelliJ 中我得到了这个奇怪的错误,为什么?

可编译代码(Eclipse 和 IntelliJ):

 System.out.println(Arrays.stream(str.split(" "))
                          .collect(Collectors.groupingBy(
                                                  Function.identity(), 
                                                  Collectors.counting())));
Run Code Online (Sandbox Code Playgroud)

错误代码(在 Eclipse 中有效,但仅在 IntelliJ 中失败):

  System.out.println(Arrays.stream(str.split(" "))
                            .collect(Collectors.groupingBy(
                                                       Function.identity(), 
                                                       HashMap::new, 
                                                       Collectors.counting())));
Run Code Online (Sandbox Code Playgroud)

IntelliJ 中第二个片段的错误

Required type: String
Provided: Map

<java.lang.String,java.lang.Long> no instance(s) of type variable(s) K, V exist so that HashMap<K, V> conforms to String
Run Code Online (Sandbox Code Playgroud)

how*_*ger 5

似乎javac是 IntelliJ IDEA 使用的一个错误。相比之下,Eclipse 有自己的编译器。

javac在 Java 8 和 11 中失败,但是如果收集器collect(...)被提取到一个var变量(自 Java 10 起可用),那么它javac在 Java 11 中编译时不会出错:

var collector = Collectors.groupingBy(Function.identity(),
                                      HashMap::new,
                                      Collectors.counting());
System.out.println(Arrays.stream(str.split(" ")).collect(collector));
Run Code Online (Sandbox Code Playgroud)

因此,可以在这里推断和使用收集器类型。

作为 的解决方法javac,您可以在 Java 8var不可用的情况下使用以下代码:

Collector<Object, ?, Map<Object, Long>> collector =
                Collectors.groupingBy(Function.identity(),
                                      HashMap::new,
                                      Collectors.counting());
System.out.println(Arrays.stream(str.split(" ")).collect(collector));
Run Code Online (Sandbox Code Playgroud)

  • @Makoto 什么是错误和正确的是由 [Java 语言规范](https://docs.oracle.com/javase/specs/) 定义的,而不是由标准实现定义的。 (4认同)
  • @Makoto 这也是错误的。Java 的 Eclipse 编译器是经过 Java 认证的(否则它甚至不能被称为“Java 编译器”,因为 Java 的使用受到需要认证才能使用的商标的保护)。因此它符合规范,严格按照规范的定义。也许规范中存在漏洞,可能会留下分歧的空间,但是,假设 Eclipse 编译器是错误的,因为它不是 javac,这对于理解规范/认证在 Java 世界中的工作方式来说是一个重大错误。 (3认同)