gpt4 book ai didi

java - 仅在 Maven 上泛型编译错误

转载 作者:行者123 更新时间:2023-11-30 07:46:54 27 4
gpt4 key购买 nike

我发现了一个编译类的问题,该问题仅发生在 Maven 中,而不是在 Eclipse 中。

代码如下:

@Test
public void compliationFailOnMaven() {

Optional<List<String>> list = getDummyList();

List<Integer> hascodes = list.orElse(Collections.EMPTY_LIST).stream().map(value -> value.hashCode()).collect(toList());

assertThat(hascodes).isNotNull();
}

private Optional<List<String>> getDummyList() {

return Optional.ofNullable(new ArrayList<String>(0));
}

如果将此代码插入到 Maven 项目中并尝试使用 mvn clean test 执行它,则会因编译问题而失败:

[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /java-tests/general-test/src/test/java/com/java8/stream/StreamTest.java:[113,125] incompatible types: java.lang.Object cannot be converted to java.util.List<java.lang.Integer>
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.844 s
[INFO] Finished at: 2015-11-19T18:07:36+01:00
[INFO] Final Memory: 26M/277M
[INFO] ------------------------------------------------------------------------

但是,如果将此项目导入到eclipse中,它可以编译并执行它,没有任何问题。

问题在于泛型的使用。如果我替换这一行:

List<Integer> hascodes = list.orElse(Collections.EMPTY_LIST).stream().map(value -> value.hashCode()).collect(toList());

这个:

List<Integer> hascodes = list.orElse(new ArrayList<String>(0)).stream().map(value -> value.hashCode()).collect(toList());

一切都可以在两个环境中运行:eclipse 和 maven。

有人知道为什么会这样吗?

为什么他们会产生不同的结果?

我只安装了一个 JVM,因此两者都使用相同的 Java 版本

最佳答案

在某些情况下可以观察到不同行为的根本原因是:Eclipse 使用自己的编译器“ECJ”,has been explained before 。相比之下,Maven 通常委托(delegate)给 javac - 虽然it can be told to use ECJ ,如果您想确保 Maven 构建显示的结果与您在 Eclipse 中看到的结果相同。

当然,两个编译器都应该遵守 JLS,从而表现出相同的行为,但实际上,由于 JLS 的复杂性,任何现实世界的编译器都会存在错误,从而导致编译器之间存在偏差。

<小时/>

对于这个给定的差异,我不明白为什么 javac 应该根据 orElse() 的参数得出不同的结果。 。注意签名:

public final class Optional<T> {
....
public T orElse(T other)
....
}

请注意,只有类是通用的,方法不是通用的。自 TList<String> (来自list的声明),orElse还返回 List<String> ,此阶段不涉及类型推断。因为我们知道一旦我们有 List<String> ,尾部应该可以正常编译。 ,任何编译器都没有理由报告错误。

唯一的问题是传递原始 List作为参数,但这完全由此位置的未经检查的警告处理。

我很惊讶地看到 javac 由于原始类型问题而拒绝程序,因为这方面的大多数问题都来自 https://bugs.openjdk.java.net/browse/JDK-8026527然而,这谈到了接纳不应该的程序。

编辑:为了完整性:我假设进行以下导入:

import java.util.*;
import static java.util.stream.Collectors.toList;

我们需要 toList 的定义完全确定会发生什么。

关于java - 仅在 Maven 上泛型编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33810237/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com