【问题标题】:Why can the Oracle Java compiler not infer the bounds here but Eclipse can?为什么 Oracle Java 编译器不能在这里推断边界,而 Eclipse 可以?
【发布时间】:2016-03-05 16:42:41
【问题描述】:

我有这个(看似)无辜的代码(在这里简化为这个 JUnit 测试用例):

import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThat;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.function.Supplier;

import org.junit.Test;

public class GenericsTest {
    private static boolean doFail;

    private static Map<String, Number> createMap() {
        if (doFail) {
            throw new IllegalArgumentException();
        }
        return new HashMap<>();
    }

    public static <T> T get(final Callable<T> _valueCreator, final Supplier<T> _errorValue) {
        try {
            return _valueCreator.call();
        } catch (final Exception e) {
            return _errorValue.get();
        }
    }

    public static Map<String, Number> getCachedMap() {
        return get(GenericsTest::createMap, Collections::emptyMap);
    }

    @Test
    public void testSuccess() {
        doFail = false;
        assertThat(getCachedMap(), instanceOf(HashMap.class));
    }

    @Test
    public void testFail() {
        doFail = true;
        assertThat(getCachedMap(), instanceOf(Collections.EMPTY_MAP.getClass()));
    }
}

问题出在return get(GenericsTest::createMap, Collections::emptyMap)这一行:Eclipse 编译器在这里没有发现问题(我也是),愉快地编译并运行测试并成功。

但是,当我在命令行上编译它时(在这种情况下是 Maven 3,Oracle JDK8,但也不能直接与 javac 一起使用),会引发编译错误:

.../GenericsTest.java:[23,19] incompatible types: inferred type does not conform to upper bound(s)
inferred: java.util.Map<? extends java.lang.Object,? extends java.lang.Object>
upper bound(s): java.util.Map<java.lang.String,java.lang.Number>,java.lang.Object

我认为从返回类型 (Map&lt;String, Number&gt;) 以及 createMap (相同) 的签名中都应该可以推断出所需的类型 - 事实上似乎 Eclipse 编译器似乎能够做到。但是,JDK 编译器只推断Map&lt;Object, Object&gt;,因此会失败。

这是 JDK 错误还是 Eclipse 编译器错误或其他什么?

【问题讨论】:

  • 他们似乎已经修复了它。我刚刚做了一些实验。它使用javac 1.8.0_65 编译,但不使用javac 1.8.0_25。我懒得找到修复这个问题的确切版本。
  • 它不能在 Ideone 上编译。 ideone.com/UDHTXm
  • @PaulBoddington 谢谢,我会试试的。我们有 1.8.0_51,所以它似乎是最近的修复。

标签: java eclipse generics compiler-errors


【解决方案1】:

这确实是一个错误,相同的代码在 JDK 1.8.0u66 上编译得很好,但在我之前的 1.8.0u51 上编译得不好。

【讨论】:

    【解决方案2】:

    这看起来像一个错误。一旦我们有更多关于为什么会发生这种情况的信息,我会处理它并可能会添加一个更好的答案。我已经提交了这个错误条目JDK-8043926 来跟踪它。

    【讨论】:

      猜你喜欢
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      • 2012-02-14
      • 1970-01-01
      • 2011-04-27
      相关资源
      最近更新 更多