【问题标题】:Why same code works in Eclipse but doesn't even compile in IntelliJ为什么相同的代码在 Eclipse 中可以工作,但在 IntelliJ 中甚至不能编译
【发布时间】:2020-01-12 04:09:29
【问题描述】:

这里有 2 个代码 sn-ps,它们应该返回相同的结果,因为我在 map factory 中使用了 HashMap。 但是第二个代码 sn-p 不能在 IntelliJ 中编译。两种代码在 Eclipse 中都能正常工作。

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

可编译代码(Eclipse 和 IntelliJ):

 System.out.println(Arrays.stream(str.split(" "))
                          .collect(Collectors.groupingBy(
                                                  Function.identity(), 
                                                  Collectors.counting())));

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

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

IntelliJ中第二个sn-p的错误

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

【问题讨论】:

  • 这段代码对我来说很好,没有错误。
  • 感谢您指出...在您发表评论后,我在 eclipse 中尝试了相同的代码并且它有效。但在 IntelliJ 中,它甚至无法编译。我将重新提出我的问题,问为什么它在 IntelliJ 中不起作用但在 eclipse 中起作用。
  • 请发布一个完整的最小示例来重现该问题,以及您从编译器获得的准确和完整的错误。

标签: eclipse intellij-idea java-8 intellij-14


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 我想说的是,因为 Eclipse 使用的是非标准编译器,所以问题在于 Eclipse 而不是 IntelliJ。 Eclipse 编译器问题有很好的记录,这就是其中之一。
  • @Makoto 什么是错什么是由Java Language Specifications 定义的,而不是标准实现。
  • 是的,这就是为什么blame Eclipse's compiler 更容易,因为它像 javac 一样严格遵循规范。
  • @Makoto 那也是错的。 Java 的 Eclipse 编译器经过 Java 认证(否则它甚至不能称为“Java 编译器”,因为 Java 的使用受到需要使用认证的商标的保护)。所以它符合规范,严格按照规范的定义。也许规范中的漏洞可以留下分歧的空间,但是,假设 Eclipse 编译器是错误的,因为它不是 javac,这是理解 Java 世界中规范/认证如何工作的一个重大错误。
  • 为了回答的完整性:在 IntelliJ IDEA 中,您可以在设置(macOS 上的首选项)中将编译器切换到 Eclipse 编译器(默认为 javac)|构建、执行、部署 |编译器 | Java 编译器 | 使用编译器并将其设置为Eclipse
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多