我有这个(貌似)无辜的代码(在这里简化为这个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 MapcreateMap() { if (doFail) { throw new IllegalArgumentException(); } return new HashMap<>(); } public static T get(final Callable _valueCreator, final Supplier _errorValue) { try { return _valueCreator.call(); } catch (final Exception e) { return _errorValue.get(); } } public static Map 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.Object
我认为从返回类型(Map
)以及createMap
(相同)的签名都应该可以推断出所需的类型 - 事实上,似乎Eclipse编译器似乎能够做到这一点.但是,JDK编译器只会推断Map
并因此失败.
这是JDK错误还是Eclipse编译器错误或其他什么?