Why doesn't the Oracle Java compiler draw borders here except Eclipse?

I have this (apparently) innocent code (this JUnit example simplified here):

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())); } } 

The problem is the return get(GenericsTest::createMap, Collections::emptyMap) line return get(GenericsTest::createMap, Collections::emptyMap) : the Eclipse compiler does not see the problem here (neither do I), it compiles and runs the test with pleasure and succeeds.

However, when I compile this on the command line (Maven 3, Oracle JDK8 in this case, but also does not work with javac directly), a compilation error occurs:

 .../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 

I would think that from the return type ( Map<String, Number> ), as well as from the signature of createMap (the same one), it should be possible to infer the required type - and in fact it seems that the Eclipse compiler seems to be able to do this. However, the JDK compiler only registers Map<Object, Object> and thus fails.

Is it a JDK error or an Eclipse compiler error or something else?

+5
source share
2 answers

It was a mistake, the same code compiles with JDK 1.8.0u66 , but not with 1.8.0u51 , which I had before.

+1
source

It looks like an error. I will take care of this and probably add a better answer if we get more information about why this is happening. I registered this JDK-8043926 error record to track it.

+3
source

Source: https://habr.com/ru/post/1237180/


All Articles